pax_global_header00006660000000000000000000000064146754575320014534gustar00rootroot0000000000000052 comment=674e4890cfddef13aaa25379473579b34e539373 django-allauth-65.0.2/000077500000000000000000000000001467545753200145205ustar00rootroot00000000000000django-allauth-65.0.2/.dir-locals.el000066400000000000000000000002531467545753200171510ustar00rootroot00000000000000;;; This file contains project-specific emacs configuration ((nil . ((python-sort-imports-on-save t) (format-all-formatters ("JavaScript" standard) ("Python" black))))) django-allauth-65.0.2/.djlintrc000066400000000000000000000000531467545753200163300ustar00rootroot00000000000000{ "custom_blocks": "element,slot,setvar" } django-allauth-65.0.2/.editorconfig000066400000000000000000000005551467545753200172020ustar00rootroot00000000000000# http://editorconfig.org root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.ini] indent_size = 4 [*.py] indent_size = 4 [*.html] indent_size = 4 [Makefile] indent_style = tab indent_size = 8 [*.md] insert_final_newline = false trim_trailing_whitespace = false django-allauth-65.0.2/.envrc000066400000000000000000000000101467545753200156250ustar00rootroot00000000000000use nix django-allauth-65.0.2/.gitea/000077500000000000000000000000001467545753200156675ustar00rootroot00000000000000django-allauth-65.0.2/.gitea/pull_request_template.md000066400000000000000000000017331467545753200226340ustar00rootroot00000000000000# Submitting Pull Requests ## General - [ ] Make sure you use [semantic commit messages](https://seesparkbox.com/foundry/semantic_commit_messages). Examples: `"fix(google): Fixed foobar bug"`, `"feat(accounts): Added foobar feature"`. - [ ] All Python code must formatted using Black, and clean from pep8 and isort issues. - [ ] JavaScript code should adhere to [StandardJS](https://standardjs.com). - [ ] If your changes are significant, please update `ChangeLog.rst`. - [ ] If your change is substantial, feel free to add yourself to `AUTHORS`. ## Provider Specifics In case you add a new provider: - [ ] Make sure unit tests are available. - [ ] Add an entry of your provider in `test_settings.py::INSTALLED_APPS` and `docs/installation.rst::INSTALLED_APPS`. - [ ] Add documentation to `docs/providers/.rst` and `docs/providers/index.rst` Provider Specifics toctree. - [ ] Add an entry to the list of supported providers over at `docs/overview.rst`. django-allauth-65.0.2/.github/000077500000000000000000000000001467545753200160605ustar00rootroot00000000000000django-allauth-65.0.2/.github/FUNDING.yml000066400000000000000000000012021467545753200176700ustar00rootroot00000000000000# These are supported funding model platforms github: pennersr patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] django-allauth-65.0.2/.github/ISSUE_TEMPLATE/000077500000000000000000000000001467545753200202435ustar00rootroot00000000000000django-allauth-65.0.2/.github/ISSUE_TEMPLATE/issue.md000066400000000000000000000004201467545753200217110ustar00rootroot00000000000000--- name: Issue about: "\U0001F6D1 Please use https://codeberg.org/allauth/django-allauth/issues" title: '' labels: '' assignees: '' --- # 🛑 Stop The issue tracker has been moved to https://codeberg.org/allauth/django-allauth/issues. Please submit your issue there. django-allauth-65.0.2/.github/SECURITY.md000066400000000000000000000001171467545753200176500ustar00rootroot00000000000000# Security Policy Please report security issues only to security@allauth.org. django-allauth-65.0.2/.github/dependabot.yml000066400000000000000000000003471467545753200207140ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" groups: GitHub_Actions: patterns: - "*" # Group all Actions updates into a single larger pull request schedule: interval: weekly django-allauth-65.0.2/.github/pull_request_template.md000066400000000000000000000001771467545753200230260ustar00rootroot00000000000000# 🛑 Stop The project has been moved to https://codeberg.org/allauth/django-allauth. Please submit your pull request there. django-allauth-65.0.2/.github/workflows/000077500000000000000000000000001467545753200201155ustar00rootroot00000000000000django-allauth-65.0.2/.github/workflows/ci.yml000066400000000000000000000061641467545753200212420ustar00rootroot00000000000000name: CI on: push: branches: [ main ] pull_request: branches: [ main ] jobs: testenv: runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: project: ['regular', 'headless_only', 'login_required_mw'] python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] django-version: ['main', '4.2', '5.0', '5.1'] exclude: - python-version: '3.8' django-version: '5.0' - python-version: '3.9' django-version: '5.0' - python-version: '3.8' django-version: '5.1' - python-version: '3.9' django-version: '5.1' - python-version: '3.8' django-version: 'main' - python-version: '3.9' django-version: 'main' # Only test LoginRequiredMiddleware on latest Python/Django. - project: 'login_required_mw' python-version: '3.8' - project: 'login_required_mw' python-version: '3.9' - project: 'login_required_mw' python-version: '3.10' - project: 'login_required_mw' python-version: '3.11' - project: 'login_required_mw' django-version: 'main' - project: 'login_required_mw' django-version: '4.2' - project: 'login_required_mw' django-version: '5.0' steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Updating package list run: sudo apt-get update - name: Install xmlsec run: sudo apt-get install -y xmlsec1 libxmlsec1-dev - name: Install dependencies run: | python -m pip install --upgrade pip pip install tox tox-gh-actions coveralls - name: Tox Test run: tox env: PYTHON_VER: ${{ matrix.python-version }} DJANGO: ${{ matrix.django-version }} PRJ: ${{ matrix.project }} - name: Coverage (Coveralls) if: ${{ success() && matrix.django-version == '5.1' && matrix.python-version == '3.12' && matrix.project == 'regular' }} run: coveralls --service=github env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} extra: runs-on: ubuntu-22.04 strategy: matrix: extra-env: ['docs', 'black', 'isort', 'flake8', 'mypy', 'standardjs', 'djlint', 'compilemessages'] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 if: ${{ matrix.extra-env == 'standardjs' }} with: node-version: '8' - name: Set up Python 3.11 uses: actions/setup-python@v5 with: python-version: '3.11' - name: Updating package list run: sudo apt-get update - name: Install xmlsec run: sudo apt-get install -y xmlsec1 libxmlsec1-dev - name: Install gettext run: sudo apt-get install -y gettext - name: Install dependencies run: | python -m pip install --upgrade pip pip install tox - name: Tox Test run: tox env: TOXENV: ${{ matrix.extra-env }} django-allauth-65.0.2/.gitignore000066400000000000000000000005421467545753200165110ustar00rootroot00000000000000*.pyc *~ .idea .project .pydevproject *.geany docs/_build build dist *.egg* examples/**/local_settings.py node_modules/ # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* coverage.xml .ropeproject/* pep8.txt *.bak .#* \#* *.db *.tmp virtualenv .DS_Store *.prefs *.mo /.stfolder .direnv/ examples/react-spa/docker-compose.override.yml django-allauth-65.0.2/.readthedocs.yaml000066400000000000000000000011341467545753200177460ustar00rootroot00000000000000# Read the Docs configuration file for Sphinx projects # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the OS, Python version and other tools you might need build: os: ubuntu-22.04 tools: python: "3.11" # Build documentation in the "docs/" directory with Sphinx sphinx: configuration: docs/conf.py # Optional but recommended, declare the Python requirements required # to build your documentation # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html python: install: - requirements: docs/requirements.txt django-allauth-65.0.2/.woodpecker.yaml000066400000000000000000000077561467545753200176430ustar00rootroot00000000000000when: - event: pull_request - event: [push, tag, manual] branch: main steps: test: image: python:${PYTHON_VERSION}-bookworm commands: - pip install tox - tox -e "prj${PRJ}-py${PYTHON_VERSION/./}-${DJANGO_VERSION}" when: - matrix: STEP: test run-py: image: python:3.12-bookworm commands: - make "ci-install-${STEP/run-py-/}" - make "${STEP/run-py-/}" when: - matrix: STEP: run-py-* standardjs: image: node:22-bookworm commands: - make ci-install-standardjs - make standardjs when: - matrix: STEP: run-js-standardjs matrix: # NOTE: Woodpecker does not seem to have support for matrix exclusion, at # least, I couldn't get it to work. Opted for handcoding the whole matrix :( include: ###################################################################### # Linters - STEP: run-py-black PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-py-mo PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-py-djlint PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-py-docs PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-py-flake8 PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-py-isort PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-py-mypy PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: run-js-standardjs PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 ###################################################################### # Regular project # Pytho 3.8/3.9 require Django <5 - STEP: test PRJ: regular DJANGO_VERSION: django42 PYTHON_VERSION: 3.8 - STEP: test PRJ: regular DJANGO_VERSION: django42 PYTHON_VERSION: 3.9 # Python 3.10+ work with django5+ - STEP: test PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.10 - STEP: test PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.11 - STEP: test PRJ: regular DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: test PRJ: regular DJANGO_VERSION: django51 PYTHON_VERSION: 3.10 - STEP: test PRJ: regular DJANGO_VERSION: django51 PYTHON_VERSION: 3.11 - STEP: test PRJ: regular DJANGO_VERSION: django51 PYTHON_VERSION: 3.12 # Only test main on latest Python - STEP: test PRJ: regular DJANGO_VERSION: djangomain PYTHON_VERSION: 3.12 ###################################################################### # Headless project # Pytho 3.8/3.9 require Django <5 - STEP: test PRJ: headless_only DJANGO_VERSION: django42 PYTHON_VERSION: 3.8 - STEP: test PRJ: headless_only DJANGO_VERSION: django42 PYTHON_VERSION: 3.9 # Python 3.10+ work with django5+ - STEP: test PRJ: headless_only DJANGO_VERSION: django50 PYTHON_VERSION: 3.10 - STEP: test PRJ: headless_only DJANGO_VERSION: django50 PYTHON_VERSION: 3.11 - STEP: test PRJ: headless_only DJANGO_VERSION: django50 PYTHON_VERSION: 3.12 - STEP: test PRJ: headless_only DJANGO_VERSION: django51 PYTHON_VERSION: 3.10 - STEP: test PRJ: headless_only DJANGO_VERSION: django51 PYTHON_VERSION: 3.11 - STEP: test PRJ: headless_only DJANGO_VERSION: django51 PYTHON_VERSION: 3.12 # Only test main on latest Python - STEP: test PRJ: headless_only DJANGO_VERSION: djangomain PYTHON_VERSION: 3.12 # Only test LoginRequiredMiddleware on latest Python/Django. - STEP: test PRJ: login_required_mw DJANGO_VERSION: django51 PYTHON_VERSION: 3.12 django-allauth-65.0.2/AUTHORS000066400000000000000000000056041467545753200155750ustar00rootroot00000000000000django-allauth was started by Raymond Penners ( or @pennersr) in October 2010, inspired by and partly based on existing projects such as Pinax (account app), Django-Socialauth, django-socialregistration. # Contributors Aarni Koskela Aaron van Derlip Abhinav Johri Abhishek Kumar Jaiswal Adam Johnson Adam McKerlie Agustin Perez Paladini Ahmet Emre Aladağ Aiden Lu Aldiantoro Nugroho Alexander Gaevsky Alfredo Altamirano Andrean Franc Andrei Satsevich Andrew Chen Wang Andrey Akolpakov Andrey Balandin Andy Matthews Ani Vera Anna Sirota Anton Goncharov Antonin Delpeuch Aron Griffis Bas ten Berge Basil Shubin Ben Timby Benjamin Howes Benjamin Jorand Bhavani Ravi Biel Massot Björn Andersson Bojan Mihelac Brandon Kong Bruno Alla Chris Beaven Chris Davis Christian Carter Christopher Grebs Dani Hodovic Daniel Eriksson Daniel Widerin David Ascher David Cain David D. Lowe David Evans David Friedman David Hummel Dimitris Tsimpitas Dmytro Litvinov Egor Poderyagin Eran Rundstein Eric Amador Eric Delord Fabio Caritas Barrionuevo da Luz Facundo Gaich Felipe Faria Filip Dobrovolný Francis Brito Frantisek Malina Fred Palmer Fábio Santos George Whewell Griffith Rees Guignard Javier Guilhem Saurel Guillaume Schurck Guillaume Vincent Guoyu Hao Haesung Park Hatem Nassrat Hyunwoo Shim Ian R-P Ignacio Ocampo Illia Volochii J. Erm J. Fernando Sánchez Jack Shedd Jakob Gerhard Martinussen James Rivett-Carnac James Thompson Jannis Leidel Jannis Vajen Jason Wallace Jeff Bowen Jeff Triplett Jeremy Satterfield Jerome Leclanche Jesse Gerard Brands Jihoon Park Jiyoon Ha Joe Vanderstelt Joel Fernandes John Bazik John Whitlock Jonas Aule JoonHwan Kim Josh Owen Josh Wright Joshua Butler Joshua Sorenson Julen Ruiz Aizpuru Justin Michalicek Justin Pogrob Karthikeyan Singaravelan Karun Shrestha Kevin Dice Kimsia Sim Koichi Harakawa Kun Liu Kyle Harrison Lee Semel Lev Predan Kowarski Luis Diego García Luiz Guilherme Pais dos Santos Luke Burden Luke Crouch Maksim Rukomoynikov Marcin Skarbek Marcin Spoczynski Marco Fucci Marjori Pomarole Markus Kaiserswerth Markus Thielen Martin Bächtold Matt Nishi-Broach Mauro Stettler Mikhail Mitiaev Morgante Pell Nariman Gharib Nathan Strobbe Nicolas Acosta Niklas A Emanuelsson Oleg Sergeev Patrick Paul Paul Juergen Fischer Paulo Eduardo Neves Pavel Oborin Pavel Savchenko Peter Bittner Peter Rowlands Peter Stein Philip John James Rabi Alam Radek Czajka Rense VanderHoek Rick Westera Robert Balfre Roberto Novaes Rod Xavier Bondoc Roman Tomjak Roumen Antonov Ryan Jarvis Ryan Verner Safwan Rahman Sam Solomon Sanghyeok Lee Seizan Shimazaki Serafeim Papastefanos Sergey Silaev Shane Rice Stephen Kent Stuart Ross Terry Jones Tiago Loureiro Tim Gates Tom Hacohen Tomas Babej Tomas Marcik Trey Corple Tuk Bredsdorff Udi Oron Victor Semionov Vlad Dmitrievich Volodymyr Yatsyk Vuong Nguyen Wendy Edwards Will Gordon Will Ross William Li Yaroslav Muravsky Youcef Mammar Yuri Kriachko django-allauth-65.0.2/ChangeLog.rst000066400000000000000000000437631467545753200171160ustar00rootroot0000000000000065.0.2 (2024-09-27) ******************* Fixes ----- - A regression occurred in the newly introduced support using ``LoginRequiredMiddleware``, fixed. - For email verification by link, it is not an issue if the user runs into rate limits. The reason is that the link is session independent. Therefore, if the user hits rate limits, we can just silently skip sending additional verification emails, as the previous emails that were already sent still contain valid links. This is different from email verification by code. Here, the session contains a specific code, meaning, silently skipping new verification emails is not an option, and we must block the login instead. The latter was missing, fixed. 65.0.1 (2024-09-23) ******************* Fixes ----- - When email verification by code was used, adding additional email addresses over at the email management page fired the ``email_added`` signal prematurely as the email address instance was still unsaved. Fixed. - The newly introduced logic to redirect to pending login stages has now been integrated in the ``RedirectAuthenticatedUserMixin`` so that the existing behavior of invoking ``get_authenticated_redirect_url()`` when already authenticated is respected. 65.0.0 (2024-09-22) ******************* Note worthy changes ------------------- - Added transparent support for Django's ``LoginRequiredMiddleware`` (new since Django 5.1). - The ``usersessions`` app now emits signals when either the IP address or user agent for a session changes. - Added support for signup using a passkey. See ``settings.MFA_PASSKEY_SIGNUP_ENABLED``. Backwards incompatible changes ------------------------------ - When the user is partially logged in (e.g. pending 2FA, or login by code), accessing the login/signup page now redirects to the pending login stage. This is similar to the redirect that was already in place when the user was fully authenticated while accessing the login/signup page. As a result, cancelling (logging out of) the pending stage requires an actual logout POST instead of merely linking back to e.g. the login page. The builtin templates handle this change transparently, but if you copied any of the templates involving the login stages you will have to adjust the cancel link into a logout POST. 64.2.1 (2024-09-05) ******************* Fixes ----- - Verifying the email address by clicking on the link would no longer log you in, even in case of ``ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True``. Security notice --------------- - It was already the case that you could not enable TOTP 2FA if your account had unverified email addresses. This is necessary to stop a user from claiming email addresses and locking other users out. This safety check is now added to WebAuthn security keys as well. - In case a user signs in into an account using social account email authentication (``SOCIALACCOUNT_EMAIL_AUTHENTICATION``) and the email used is not verified, the password of the account is now wiped (made unusable) to prevent the person that created the account (without verifying it) from signing in. 64.2.0 (2024-08-30) ******************* Note worthy changes ------------------- - Verifying email addresses by means of a code (instead of a link) is now supported. See ``settings.ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED``. - Added support for requiring logging in by code, so that every user logging in is required to input a login confirmation code sent by email. See ``settings.ACCOUNT_LOGIN_BY_CODE_REQUIRED``. Security notice --------------- - In case an ID token is used for authentication, the JTI is now respected to prevent the possibility of replays instead of solely relying on the expiration time. 64.1.0 (2024-08-15) ******************* Note worthy changes ------------------- - Headless: When trying to login while a user is already logged in, you now get a 409. - Limited the maximum allowed time for a login to go through the various login stages. This limits, for example, the time span that the 2FA stage remains available. See ``settings.ACCOUNT_LOGIN_TIMEOUT``. Security notice --------------- - Headless: When a user was not fully logged in, for example, because (s)he was in the process of completing the 2FA process, calling logout would not wipe the session containing the partially logged in user. 64.0.0 (2024-07-31) ******************* Note worthy changes ------------------- - The 0.x.y version numbers really did not do justice to the state of the project, and we are way past the point where a version 1.0 would be applicable. Additionally, 64 is a nice round number. Therefore, the version numbering is changed from 0.x.y to x.y.z. We will use a loose form of semantic versioning. However, please be aware that feature releases may occasionally include minor documented backwards incompatibilities. Always read the release notes before upgrading. - Added support for WebAuthn based security keys and passkey login. Note that this is currently disabled by default. - Headless: The TOTP URI is now available in the MFA activation response. - Headless: When trying to sign up while a user is already logged in, you now get a 409. - Headless: You can now alter the user data payload by overriding the newly introduced ``serialize_user()`` adapter method. - Headless: The token strategy now allows for exposing refresh tokens and any other information you may need (such as e.g. ``expires_in``). - Ensured that email address, given name and family name fields are stored in the SocialAccount instance. This information was not previously saved in Amazon Cognito, Edmodo, and MediaWiki SocialAccount instances. - When multiple third-party accounts of the same provider were connected, the third-party account connections overview did not always provide a clear recognizable distinction between those accounts. Now, the ``SocialAccount.__str__()`` has been altered to return the unique username or email address, rather than a non-unique display name. Backwards incompatible changes ------------------------------ - Dropped support for Django 3.2, 4.0 and 4.1 (which all reached end of life). As Django 3.2 was the last to support Python 3.7, support for Python 3.7 is now dropped as well. 0.63.6 (2024-07-12) ******************* Security notice --------------- - When the Facebook provider was configured to use the ``js_sdk`` method the login page could become vulnerable to an XSS attack. 0.63.5 (2024-07-11) ******************* Fixes ----- - The security fix in 0.63.4 that altered the ``__str__()`` of ``SocialToken`` caused issues within the Amazon Cognito, Atlassian, JupyterHub, LemonLDAP, Nextcloud and OpenID Connect providers. Fixed. 0.63.4 (2024-07-10) ******************* Security notice --------------- - The ``__str__()`` method of the ``SocialToken`` model returned the access token. As a consequence, logging or printing tokens otherwise would expose the access token. Now, the method no longer returns the token. If you want to log/print tokens, you will now have to explicitly log the ``token`` field of the ``SocialToken`` instance. - Enumeration prevention: the behavior on the outside of an actual signup versus a signup where the user already existed was not fully identical, fixed. 0.63.3 (2024-05-31) ******************* Note worthy changes ------------------- - In ``HEADLESS_ONLY`` mode, the ``/accounts//login/`` URLs were still available, fixed. - The few remaining OAuth 1.0 providers were not compatible with headless mode, fixed. - Depending on where you placed the ``secure_admin_login(admin.site.login)`` protection you could run into circular import errors, fixed. Backwards incompatible changes ------------------------------ - SAML: IdP initiated SSO is disabled by default, see security notice below. Security notice --------------- - SAML: ``RelayState`` was used to keep track of whether or not the login flow was IdP or SP initiated. As ``RelayState`` is a separate field, not part of the ``SAMLResponse`` payload, it is not signed and thereby making the SAML login flow vulnerable to CSRF/replay attacks. Now, ``InResponseTo`` is used instead, addressing the issue for SP initiated SSO flows. IdP initiated SSO remains inherently insecure, by design. For that reason, it is now disabled by default. If you need to support IdP initiated SSO, you will need to opt-in to that by adding ``"reject_idp_initiated_sso": False`` to your advanced SAML provider settings. 0.63.2 (2024-05-24) ******************* Note worthy changes ------------------- - ``allauth.headless`` now supports the ``is_open_for_signup()`` adapter method. In case signup is closed, a 403 is returned during signup. - Connecting a third-party account in ``HEADLESS_ONLY`` mode failed if the connections view could not be reversed, fixed. - In case a headless attempt was made to connect a third-party account that was already connected to a different account, no error was communicated to the frontend. Fixed. - When the headless provider signup endpoint was called while that flow was not pending, a crash would occur. This has been fixed to return a 409 (conflict). - Microsoft provider: the URLs pointing to the login and graph API are now configurable via the app settings. 0.63.1 (2024-05-17) ******************* Note worthy changes ------------------- - When only ``allauth.account`` was installed, you could run into an exception stating "allauth.socialaccount not installed, yet its models are imported.". This has been fixed. - When ``SOCIALACCOUNT_EMAIL_AUTHENTICATION`` was turned on, and a user would connect a third-party account for which email authentication would kick in, the connect was implicitly skipped. Fixed. - The recommendation from the documentation to protect the Django admin login could cause an infinite redirect loop in case of ``AUTHENTICATED_LOGIN_REDIRECTS``. A decorator ``secure_admin_login()`` is now offered out of the box to ensure that the Django admin is properly secured by allauth (e.g. rate limits, 2FA). - Subpackages from the ``tests`` package were packaged, fixed. 0.63.0 (2024-05-14) ******************* Note worthy changes ------------------- - New providers: TikTok, Lichess. - Starting since version 0.62.0, new email addresses are always stored as lower case. In this version, we take the final step and also convert existing data to lower case, alter the database indices and perform lookups accordingly. Migrations are in place. For rationale, see the note about email case sensitivity in the documentation. - An official API for single-page and mobile application support is now available, via the new ``allauth.headless`` app. - Added support for a honeypot field on the signup form. Real users do not see the field and therefore leave it empty. When bots do fill out the field account creation is silently skipped. 0.62.1 (2024-04-24) ******************* - The ``tests`` package was accidentally packaged, fixed. 0.62.0 (2024-04-22) ******************* Note worthy changes ------------------- - Added a dummy provider, useful for testing purposes: ``allauth.socialaccount.providers.dummy``. - Added a new provider, Atlassian - Next URL handling been streamlined to be consistently applied. Previously, the password reset, change and email confirmation views only supported the ``success_url`` class-level property. - Added support for logging in by email using a special code, also known as "Magic Code Login" - Email addresses are now always stored as lower case. For rationale, see the note about email case sensitivity in the documentation. - You can now alter the ``state`` parameter that is typically passed to the provider by overriding the new ``generate_state_param()`` adapter method. - The URLs were not "hackable". For example, while ``/accounts/login/`` is valid ``/accounts/`` was not. Similarly, ``/accounts/social/connections/`` was valid, but ``/accounts/social/`` resulted in a 404. This has been addressed. Now, ``/accounts/`` redirects to the login or email management page, depending on whether or not the user is authenticated. All ``/accounts/social/*`` URLs are now below ``/accounts/3rdparty/*``, where ``/accounts/social/connections`` is moved to the top-level ``/accounts/3rdparty/``. The old endpoints still work as redirects are in place. - Added a new setting, ``SOCIALACCOUNT_ONLY``, which when set to ``True``, disables all functionality with respect to local accounts. - The OAuth2 handshake was not working properly in case of ``SESSION_COOKIE_SAMESITE = "Strict"``, fixed. - Facebook: the default Graph API version is now v19.0. Backwards incompatible changes ------------------------------ - The django-allauth required dependencies are now more fine grained. If you do not use any of the social account functionality, a ``pip install django-allauth`` will, e.g., no longer pull in dependencies for handling JWT. If you are using social account functionality, install using ``pip install "django-allauth[socialaccount]"``. That will install the dependencies covering most common providers. If you are using the Steam provider, install using ``pip install django-allauth[socialaccount,steam]``. 0.61.1 (2024-02-09) ******************* Fixes ----- - Fixed a ``RuntimeWarning`` that could occur when running inside an async environment (``'SyncToAsync' was never awaited``). Security notice --------------- - As part of the Google OAuth handshake, an ID token is obtained by direct machine to machine communication between the server running django-allauth and Google. Because of this direct communication, we are allowed to skip checking the token signature according to the `OpenID Connect Core 1.0 specification `_. However, as django-allauth is used and built upon by third parties, this is an implementation detail with security implications that is easily overlooked. To mitigate potential issues, verifying the signature is now only skipped if it was django-allauth that actually fetched the access token. 0.61.0 (2024-02-07) ******************* Note worthy changes ------------------- - Added support for account related security notifications. When ``ACCOUNT_EMAIL_NOTIFICATIONS = True``, email notifications such as "Your password was changed", including information on user agent / IP address from where the change originated, will be emailed. - Google: Starting from 0.52.0, the ``id_token`` is being used for extracting user information. To accommodate for scenario's where django-allauth is used in contexts where the ``id_token`` is not posted, the provider now looks up the required information from the ``/userinfo`` endpoint based on the access token if the ``id_token`` is absent. Security notice --------------- - MFA: It was possible to reuse a valid TOTP code within its time window. This has now been addressed. As a result, a user can now only login once per 30 seconds (``MFA_TOTP_PERIOD``). Backwards incompatible changes ------------------------------ - The rate limit mechanism has received an update. Previously, when specifying e.g. ``"5/m"`` it was handled implicitly whether or not that limit was per IP, per user, or per action specific key. This has now been made explicit: ``"5/m/user"`` vs ``"5/m/ip"`` vs ``"5/m/key"``. Combinations are also supported now: ``"20/m/ip,5/m/key"`` . Additionally, the rate limit mechanism is now used throughout, including email confirmation cooldown as well as limitting failed login attempts. Therefore, the ``ACCOUNT_LOGIN_ATTEMPTS_LIMIT`` and ``ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN`` settings are deprecated. See :doc:`Rate Limits <../account/rate_limits>` for details. 0.60.1 (2024-01-15) ******************* Fixes ----- - User sessions: after changing your password in case of ``ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = False``, the list of sessions woud be empty instead of showing your current session. - SAML: accessing the SLS/ACS views using a GET request would result in a crash (500). - SAML: the login view did not obey the ``SOCIALACCOUNT_LOGIN_ON_GET = False`` setting. Backwards incompatible changes ------------------------------ - Formally, email addresses are case sensitive because the local part (the part before the "@") can be a case sensitive user name. To deal with this, workarounds have been in place for a long time that store email addresses in their original case, while performing lookups in a case insensitive style. This approach led to subtle bugs in upstream code, and also comes at a performance cost (``__iexact`` lookups). The latter requires case insensitive index support, which not all databases support. Re-evaluating the approach in current times has led to the conclusion that the benefits do not outweigh the costs. Therefore, email addresses are now always stored as lower case, and migrations are in place to address existing records. 0.60.0 (2024-01-05) ******************* Note worthy changes ------------------- - Google One Tap Sign-In is now supported. - You can now more easily change the URL to redirect to after a successful password change/set via the newly introduced ``get_password_change_redirect_url()`` adapter method. - You can now configure the primary key of all models by configuring ``ALLAUTH_DEFAULT_AUTO_FIELD``, for example to: ``"hashid_field.HashidAutoField"``. Backwards incompatible changes ------------------------------ - You can now specify the URL path prefix that is used for all OpenID Connect providers using ``SOCIALACCOUNT_OPENID_CONNECT_URL_PREFIX``. By default, it is set to ``"oidc"``, meaning, an OpenID Connect provider with provider ID ``foo`` uses ``/accounts/oidc/foo/login/`` as its login URL. Set it to empty (``""``) to keep the previous URL structure (``/accounts/foo/login/``). - The SAML default attribute mapping for ``uid`` has been changed to only include ``urn:oasis:names:tc:SAML:attribute:subject-id``. If the SAML response does not contain that, it will fallback to use ``NameID``. django-allauth-65.0.2/LICENSE000066400000000000000000000021201467545753200155200ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2010-2021 Raymond Penners and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. django-allauth-65.0.2/MANIFEST.in000066400000000000000000000002631467545753200162570ustar00rootroot00000000000000include AUTHORS include LICENSE include README.rst include ChangeLog.rst recursive-include allauth *.html *.txt *.xml *.po *.mo *.js recursive-include docs Makefile conf.py *.rst django-allauth-65.0.2/Makefile000066400000000000000000000035431467545753200161650ustar00rootroot00000000000000PYTHON = python .PHONY: usage usage: @echo 'Usage: make [target]' .PHONY: po po: ( cd allauth ; $(PYTHON) ../manage.py makemessages -a -e html,txt,py ) .PHONY: mo mo: ( cd allauth ; $(PYTHON) ../manage.py compilemessages ) .PHONY: isort isort: isort --check-only --diff . .PHONY: black black: black --check . .PHONY: test test: pytest allauth/ .PHONY: djlint djlint: djlint --check allauth examples .PHONY: flake8 flake8: flake8 allauth .PHONY: qa qa: validate-api-spec mypy djlint black isort flake8 .PHONY: mypy mypy: mypy allauth/ .PHONY: validate-api-spec validate-api-spec: swagger-cli validate docs/headless/openapi-specification/openapi.yaml .PHONY: ci ci: woodpecker-cli exec .woodpecker.yaml .PHONY: standardjs standardjs: find ./allauth -name '*.js' | xargs ./node_modules/.bin/standard --ignore allauth/mfa/static/mfa/js/webauthn-json.js .PHONY: docs docs: $(MAKE) -C docs html .PHONY: ci-install-black ci-install-black: pip install black==24.4.0 .PHONY: ci-install-mo ci-install-mo: apt-get update apt-get install -y --no-install-recommends gettext pip install .[mfa,socialaccount,openid,saml] .PHONY: ci-install-standardjs ci-install-standardjs: npm install standard --no-lockfile --no-progress --non-interactive --silent .PHONY: ci-install-djlint ci-install-djlint: pip install djlint==1.34.1 .PHONY: ci-install-docs ci-install-docs: pip install Django Sphinx sphinx_rtd_theme .PHONY: ci-install-flake8 ci-install-flake8: pip install flake8==7.1.1 .PHONY: ci-install-isort ci-install-isort: pip install isort==5.13.2 .PHONY: ci-install-mypy ci-install-mypy: pip install .[mfa,socialaccount,openid,saml] pip install \ 'django-stubs==5.0.2' \ 'mypy==1.10.0' \ 'pytest>=7.4' \ 'pytest-asyncio == 0.23.8' \ 'pytest-django>=4.5.2' \ 'types-requests==2.32.0.20240602' \ 'python3-saml>=1.15.0,<2.0.0' django-allauth-65.0.2/README.rst000066400000000000000000000145431467545753200162160ustar00rootroot00000000000000 ========================== Welcome to django-allauth! ========================== .. image:: https://codeberg.org/allauth/allauth.org/raw/commit/da3b56390e1b18eaec09b05cd89dfa7812212dfc/content/news/2024/04/website-redesign/logo-light.png :target: https://allauth.org :align: right :alt: django-allauth logo :width: 250px .. |ci| image:: https://img.shields.io/github/actions/workflow/status/pennersr/django-allauth/ci.yml.svg :target: https://github.com/pennersr/django-allauth/actions .. |pypi| image:: https://img.shields.io/pypi/v/django-allauth :target: https://pypi.python.org/pypi/django-allauth .. |cov| image:: https://img.shields.io/coverallsCoverage/github/pennersr/django-allauth :alt: Coverage Status :target: https://coveralls.io/r/pennersr/django-allauth .. |btc| image:: https://img.shields.io/badge/bitcoin-donate-yellow :target: https://blockchain.info/address/1AJXuBMPHkaDCNX2rwAy34bGgs7hmrePEr .. |liberapay| image:: https://img.shields.io/liberapay/receives/pennersr :target: https://en.liberapay.com/pennersr .. |pystyle| image:: https://img.shields.io/badge/code_style-pep8-green :target: https://www.python.org/dev/peps/pep-0008/ .. |jsstyle| image:: https://img.shields.io/badge/code_style-standard-brightgreen :target: http://standardjs.com .. |editor| image:: https://img.shields.io/badge/editor-emacs-purple :target: https://www.gnu.org/software/emacs/ .. |i18n| image:: https://img.shields.io/weblate/progress/allauth :target: https://hosted.weblate.org/projects/allauth/django-allauth/ .. |pypidl| image:: https://img.shields.io/pypi/dm/django-allauth :target: https://pypistats.org/packages/django-allauth :alt: PyPI - Downloads .. |djangodemo| image:: https://img.shields.io/badge/%E2%96%B6_demo-Django_project-red :target: https://django.demo.allauth.org/ :alt: View Django Demo .. |reactdemo| image:: https://img.shields.io/badge/%E2%96%B6_demo-React_SPA-red :target: https://react.demo.allauth.org/ :alt: View React SPA Demo |ci| |pypi| |cov| |btc| |liberapay| |pystyle| |jsstyle| |editor| |i18n| |pypidl| |djangodemo| |reactdemo| Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication. Home page https://allauth.org/ Source code https://codeberg.org/allauth/django-allauth Issue Tracker https://codeberg.org/allauth/django-allauth/issues Documentation https://docs.allauth.org/en/latest/ Stack Overflow https://stackoverflow.com/questions/tagged/django-allauth Demo https://django.demo.allauth.org and https://react.demo.allauth.org Translations https://hosted.weblate.org/projects/allauth/django-allauth/ .. end-welcome Rationale ========= .. begin-rationale Most existing Django apps that address the problem of social authentication unfortunately focus only on one dimension - the social. Most developers end up integrating another app in order to support authentication flows that are locally generated. This approach creates a development gap between local and social authentication flows. It has remained an issue in spite of numerous common scenarios that both require. For example, an email address passed along by an OpenID provider may not be verified. Therefore, prior to hooking up an OpenID account to a local account the email address must be verified. This essentially is one of many use cases that mandate email verification to be present in both worlds. Integrating both is a humongous and tedious process. It is not as simple as adding one social authentication app, and one local account registration app to your ``INSTALLED_APPS`` list. This inadequacy is the reason for this project's existence -- to offer a fully integrated authentication app that allows for both local and social authentication, with flows that just work, beautifully! .. end-rationale Features ======== .. begin-features **🔑 Comprehensive account functionality** Supports multiple authentication schemes (e.g. login by user name, or by email), as well as multiple strategies for account verification (ranging from none to mandatory email verification). **👥 Social Login** Login using external identity providers, supporting any *Open ID Connect compatible* provider, many *OAuth 1.0/2.0* providers, as well as custom protocols such as, for example, *Telegram* authentication. **💼 Enterprise ready** Supports SAML 2.0, which is often used in a B2B context. **🕵️ Battle-tested** The package has been out in the open since 2010. It is in use by many commercial companies whose business depends on it and has hence been subjected to various penetration testing attempts. **⏳Rate limiting** When you expose an authentication-enabled web service to the internet, it is important to be prepared for potential brute force attempts. Therefore, rate limiting is enabled out of the box. **🔒 Private** Many sites leak information. For example, on many sites you can check whether someone you know has an account by input their email address into the password forgotten form, or trying to signup with it. We offer account enumeration prevention, making it impossible to tell whether or not somebody already has an account. **🧩 Customizable** As a developer, you have the flexibility to customize the core functionality according to your specific requirements. By employing the adapter pattern, you can effortlessly introduce interventions at the desired points to deviate from the standard behavior. This level of customization empowers you to tailor the software to meet your unique needs and preferences. **⚙️ Configuration** The required consumer keys and secrets for interacting with Facebook, X (Twitter) and the likes can be configured using regular settings, or, can be configured in the database via the Django admin. Here, optional support for the Django sites framework is available, which is helpful for larger multi-domain projects, but also allows for easy switching between a development (localhost) and production setup without messing with your settings and database. .. end-features Commercial Support ================== .. begin-support Commercial support is available. If you find certain functionality missing, or require assistance on your project(s), please contact us: info@intenct.nl. .. end-support django-allauth-65.0.2/allauth/000077500000000000000000000000001467545753200161525ustar00rootroot00000000000000django-allauth-65.0.2/allauth/__init__.py000066400000000000000000000012641467545753200202660ustar00rootroot00000000000000r""" _ ___ __ __ .___________. __ __ /\| |/\ / \ | | | | | || | | | \ ` ' / / ^ \ | | | | `---| |----`| |__| | |_ _| / /_\ \ | | | | | | | __ | / , . \ / _____ \ | `--' | | | | | | | \/|_|\//__/ \__\ \______/ |__| |__| |__| """ VERSION = (65, 0, 2, "final", 0) __title__ = "django-allauth" __version_info__ = VERSION __version__ = ".".join(map(str, VERSION[:3])) + ( "-{}{}".format(VERSION[3], VERSION[4] or "") if VERSION[3] != "final" else "" ) __author__ = "Raymond Penners" __license__ = "MIT" __copyright__ = "Copyright 2010-2024 Raymond Penners and contributors" django-allauth-65.0.2/allauth/account/000077500000000000000000000000001467545753200176065ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/__init__.py000066400000000000000000000000001467545753200217050ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/adapter.py000066400000000000000000000721761467545753200216150ustar00rootroot00000000000000import html import json import string import warnings from urllib.parse import urlparse from django.conf import settings from django.contrib import messages from django.contrib.auth import ( authenticate, get_backends, get_user_model, login as django_login, logout as django_logout, ) from django.contrib.auth.models import AbstractUser from django.contrib.auth.password_validation import ( MinimumLengthValidator, validate_password, ) from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import FieldDoesNotExist from django.core.mail import EmailMessage, EmailMultiAlternatives from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import resolve_url from django.template import TemplateDoesNotExist from django.template.loader import render_to_string from django.urls import reverse from django.utils import timezone from django.utils.crypto import get_random_string from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ from allauth import app_settings as allauth_app_settings from allauth.account import app_settings, signals from allauth.core import context, ratelimit from allauth.core.internal.adapter import BaseAdapter from allauth.core.internal.httpkit import headed_redirect_response from allauth.utils import generate_unique_username, import_attribute class DefaultAccountAdapter(BaseAdapter): """The adapter class allows you to override various functionality of the ``allauth.account`` app. To do so, point ``settings.ACCOUNT_ADAPTER`` to your own class that derives from ``DefaultAccountAdapter`` and override the behavior by altering the implementation of the methods according to your own needs. """ error_messages = { "account_inactive": _("This account is currently inactive."), "cannot_remove_primary_email": _( "You cannot remove your primary email address." ), "duplicate_email": _( "This email address is already associated with this account." ), "email_password_mismatch": _( "The email address and/or password you specified are not correct." ), "email_taken": _("A user is already registered with this email address."), "enter_current_password": _("Please type your current password."), "incorrect_code": _("Incorrect code."), "incorrect_password": _("Incorrect password."), "invalid_or_expired_key": _("Invalid or expired key."), "invalid_password_reset": _("The password reset token was invalid."), "max_email_addresses": _("You cannot add more than %d email addresses."), "too_many_login_attempts": _( "Too many failed login attempts. Try again later." ), "unknown_email": _("The email address is not assigned to any user account"), "unverified_primary_email": _("Your primary email address must be verified."), "username_blacklisted": _( "Username can not be used. Please use other username." ), "username_password_mismatch": _( "The username and/or password you specified are not correct." ), "username_taken": AbstractUser._meta.get_field("username").error_messages[ "unique" ], } def stash_verified_email(self, request, email): request.session["account_verified_email"] = email def unstash_verified_email(self, request): ret = request.session.get("account_verified_email") request.session["account_verified_email"] = None return ret def is_email_verified(self, request, email): """ Checks whether or not the email address is already verified beyond allauth scope, for example, by having accepted an invitation before signing up. """ ret = False verified_email = request.session.get("account_verified_email") if verified_email: ret = verified_email.lower() == email.lower() return ret def can_delete_email(self, email_address) -> bool: """ Returns whether or not the given email address can be deleted. """ from allauth.account.models import EmailAddress has_other = ( EmailAddress.objects.filter(user_id=email_address.user_id) .exclude(pk=email_address.pk) .exists() ) login_by_email = ( app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.EMAIL ) if email_address.primary: if has_other: # Don't allow, let the user mark one of the others as primary # first. return False elif login_by_email: # Last email & login is by email, prevent dangling account. return False return True elif has_other: # Account won't be dangling. return True elif login_by_email: # This is the last email. return False else: return True def format_email_subject(self, subject) -> str: """ Formats the given email subject. """ prefix = app_settings.EMAIL_SUBJECT_PREFIX if prefix is None: site = get_current_site(context.request) prefix = "[{name}] ".format(name=site.name) return prefix + force_str(subject) def get_from_email(self): """ This is a hook that can be overridden to programmatically set the 'from' email address for sending emails """ return settings.DEFAULT_FROM_EMAIL def render_mail(self, template_prefix, email, context, headers=None): """ Renders an email to `email`. `template_prefix` identifies the email that is to be sent, e.g. "account/email/email_confirmation" """ to = [email] if isinstance(email, str) else email subject = render_to_string("{0}_subject.txt".format(template_prefix), context) # remove superfluous line breaks subject = " ".join(subject.splitlines()).strip() subject = self.format_email_subject(subject) from_email = self.get_from_email() bodies = {} html_ext = app_settings.TEMPLATE_EXTENSION for ext in [html_ext, "txt"]: try: template_name = "{0}_message.{1}".format(template_prefix, ext) bodies[ext] = render_to_string( template_name, context, globals()["context"].request, ).strip() except TemplateDoesNotExist: if ext == "txt" and not bodies: # We need at least one body raise if "txt" in bodies: msg = EmailMultiAlternatives( subject, bodies["txt"], from_email, to, headers=headers ) if html_ext in bodies: msg.attach_alternative(bodies[html_ext], "text/html") else: msg = EmailMessage( subject, bodies[html_ext], from_email, to, headers=headers ) msg.content_subtype = "html" # Main content is now text/html return msg def send_mail(self, template_prefix, email, context): ctx = { "email": email, "current_site": get_current_site(globals()["context"].request), } ctx.update(context) msg = self.render_mail(template_prefix, email, ctx) msg.send() def get_signup_redirect_url(self, request): return resolve_url(app_settings.SIGNUP_REDIRECT_URL) def get_login_redirect_url(self, request): """ Returns the default URL to redirect to after logging in. Note that URLs passed explicitly (e.g. by passing along a `next` GET parameter) take precedence over the value returned here. """ assert request.user.is_authenticated url = getattr(settings, "LOGIN_REDIRECT_URLNAME", None) if url: warnings.warn( "LOGIN_REDIRECT_URLNAME is deprecated, simply" " use LOGIN_REDIRECT_URL with a URL name", DeprecationWarning, ) else: url = settings.LOGIN_REDIRECT_URL return resolve_url(url) def get_logout_redirect_url(self, request): """ Returns the URL to redirect to after the user logs out. Note that this method is also invoked if you attempt to log out while no users is logged in. Therefore, request.user is not guaranteed to be an authenticated user. """ return resolve_url(app_settings.LOGOUT_REDIRECT_URL) def get_email_verification_redirect_url(self, email_address): """ The URL to return to after email verification. """ get_url = getattr(self, "get_email_confirmation_redirect_url", None) if get_url: # Deprecated. return get_url(self.request) if self.request.user.is_authenticated: if app_settings.EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL: return app_settings.EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL else: return self.get_login_redirect_url(self.request) else: return app_settings.EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL def get_password_change_redirect_url(self, request): """ The URL to redirect to after a successful password change/set. NOTE: Not called during the password reset flow. """ return reverse("account_change_password") def is_open_for_signup(self, request): """ Checks whether or not the site is open for signups. Next to simply returning True/False you can also intervene the regular flow by raising an ImmediateHttpResponse """ return True def new_user(self, request): """ Instantiates a new User instance. """ user = get_user_model()() return user def populate_username(self, request, user): """ Fills in a valid username, if required and missing. If the username is already present it is assumed to be valid (unique). """ from .utils import user_email, user_field, user_username first_name = user_field(user, "first_name") last_name = user_field(user, "last_name") email = user_email(user) username = user_username(user) if app_settings.USER_MODEL_USERNAME_FIELD: user_username( user, username or self.generate_unique_username( [first_name, last_name, email, username, "user"] ), ) def generate_unique_username(self, txts, regex=None): return generate_unique_username(txts, regex) def save_user(self, request, user, form, commit=True): """ Saves a new `User` instance using information provided in the signup form. """ from .utils import user_email, user_field, user_username data = form.cleaned_data first_name = data.get("first_name") last_name = data.get("last_name") email = data.get("email") username = data.get("username") user_email(user, email) user_username(user, username) if first_name: user_field(user, "first_name", first_name) if last_name: user_field(user, "last_name", last_name) if "password1" in data: user.set_password(data["password1"]) elif "password" in data: user.set_password(data["password"]) else: user.set_unusable_password() self.populate_username(request, user) if commit: # Ability not to commit makes it easier to derive from # this adapter by adding user.save() return user def clean_username(self, username, shallow=False): """ Validates the username. You can hook into this if you want to (dynamically) restrict what usernames can be chosen. """ for validator in app_settings.USERNAME_VALIDATORS: validator(username) # TODO: Add regexp support to USERNAME_BLACKLIST username_blacklist_lower = [ ub.lower() for ub in app_settings.USERNAME_BLACKLIST ] if username.lower() in username_blacklist_lower: raise self.validation_error("username_blacklisted") # Skipping database lookups when shallow is True, needed for unique # username generation. if not shallow: from .utils import filter_users_by_username if filter_users_by_username(username).exists(): raise self.validation_error("username_taken") return username def clean_email(self, email): """ Validates an email value. You can hook into this if you want to (dynamically) restrict what email addresses can be chosen. """ return email def clean_password(self, password, user=None): """ Validates a password. You can hook into this if you want to restric the allowed password choices. """ min_length = app_settings.PASSWORD_MIN_LENGTH if min_length: MinimumLengthValidator(min_length).validate(password) validate_password(password, user) return password def validate_unique_email(self, email): return email def add_message( self, request, level, message_template=None, message_context=None, extra_tags="", message=None, ): """ Wrapper of `django.contrib.messages.add_message`, that reads the message text from a template. """ if getattr(getattr(request, "allauth", None), "headless", None): return if "django.contrib.messages" in settings.INSTALLED_APPS: if message: messages.add_message(request, level, message, extra_tags=extra_tags) return try: if message_context is None: message_context = {} escaped_message = render_to_string( message_template, message_context, context.request, ).strip() if escaped_message: message = html.unescape(escaped_message) messages.add_message(request, level, message, extra_tags=extra_tags) except TemplateDoesNotExist: pass def ajax_response(self, request, response, redirect_to=None, form=None, data=None): resp = {} status = response.status_code if redirect_to: status = 200 resp["location"] = redirect_to if form: if request.method == "POST": if form.is_valid(): status = 200 else: status = 400 else: status = 200 resp["form"] = self.ajax_response_form(form) if hasattr(response, "render"): response.render() resp["html"] = response.content.decode("utf8") if data is not None: resp["data"] = data return HttpResponse( json.dumps(resp), status=status, content_type="application/json" ) def ajax_response_form(self, form): form_spec = { "fields": {}, "field_order": [], "errors": form.non_field_errors(), } for field in form: field_spec = { "label": force_str(field.label), "value": field.value(), "help_text": force_str(field.help_text), "errors": [force_str(e) for e in field.errors], "widget": { "attrs": { k: force_str(v) for k, v in field.field.widget.attrs.items() } }, } form_spec["fields"][field.html_name] = field_spec form_spec["field_order"].append(field.html_name) return form_spec def pre_login( self, request, user, *, email_verification, signal_kwargs, email, signup, redirect_url ): if not user.is_active: return self.respond_user_inactive(request, user) def post_login( self, request, user, *, email_verification, signal_kwargs, email, signup, redirect_url ): from .utils import get_login_redirect_url response = HttpResponseRedirect( get_login_redirect_url(request, redirect_url, signup=signup) ) if signal_kwargs is None: signal_kwargs = {} signals.user_logged_in.send( sender=user.__class__, request=request, response=response, user=user, **signal_kwargs, ) self.add_message( request, messages.SUCCESS, "account/messages/logged_in.txt", {"user": user}, ) return response def login(self, request, user): # HACK: This is not nice. The proper Django way is to use an # authentication backend if not hasattr(user, "backend"): from .auth_backends import AuthenticationBackend backends = get_backends() backend = None for b in backends: if isinstance(b, AuthenticationBackend): # prefer our own backend backend = b break elif not backend and hasattr(b, "get_user"): # Pick the first valid one backend = b backend_path = ".".join([backend.__module__, backend.__class__.__name__]) user.backend = backend_path django_login(request, user) def logout(self, request): django_logout(request) def confirm_email(self, request, email_address): """ Marks the email address as confirmed on the db """ from allauth.account.internal.flows import email_verification return email_verification.verify_email(request, email_address) def set_password(self, user, password) -> None: """ Sets the password for the user. """ user.set_password(password) user.save() def get_user_search_fields(self): ret = [] User = get_user_model() candidates = [ app_settings.USER_MODEL_USERNAME_FIELD, "first_name", "last_name", "email", ] for candidate in candidates: try: User._meta.get_field(candidate) ret.append(candidate) except FieldDoesNotExist: pass return ret def is_safe_url(self, url): from django.utils.http import url_has_allowed_host_and_scheme # get_host already validates the given host, so no need to check it again allowed_hosts = {context.request.get_host()} | set(settings.ALLOWED_HOSTS) if "*" in allowed_hosts: parsed_host = urlparse(url).netloc allowed_host = {parsed_host} if parsed_host else None return url_has_allowed_host_and_scheme(url, allowed_hosts=allowed_host) return url_has_allowed_host_and_scheme(url, allowed_hosts=allowed_hosts) def send_password_reset_mail(self, user, email, context): """ Method intended to be overridden in case you need to customize the logic used to determine whether a user is permitted to request a password reset. For example, if you are enforcing something like "social only" authentication in your app, you may want to intervene here by checking `user.has_usable_password` """ return self.send_mail("account/email/password_reset_key", email, context) def get_reset_password_from_key_url(self, key): """ Method intended to be overridden in case the password reset email needs to be adjusted. """ from allauth.account.internal import flows return flows.password_reset.get_reset_password_from_key_url(self.request, key) def get_email_confirmation_url(self, request, emailconfirmation): """Constructs the email confirmation (activation) url. Note that if you have architected your system such that email confirmations are sent outside of the request context `request` can be `None` here. """ from allauth.account.internal import flows return flows.email_verification.get_email_verification_url( request, emailconfirmation ) def should_send_confirmation_mail(self, request, email_address, signup) -> bool: return True def send_account_already_exists_mail(self, email): from allauth.account.internal import flows signup_url = flows.signup.get_signup_url(context.request) password_reset_url = flows.password_reset.get_reset_password_url( context.request ) ctx = { "request": context.request, "signup_url": signup_url, "password_reset_url": password_reset_url, } self.send_mail("account/email/account_already_exists", email, ctx) def send_confirmation_mail(self, request, emailconfirmation, signup): ctx = { "user": emailconfirmation.email_address.user, } if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: ctx.update({"code": emailconfirmation.key}) else: ctx.update( { "key": emailconfirmation.key, "activate_url": self.get_email_confirmation_url( request, emailconfirmation ), } ) if signup: email_template = "account/email/email_confirmation_signup" else: email_template = "account/email/email_confirmation" self.send_mail(email_template, emailconfirmation.email_address.email, ctx) def respond_user_inactive(self, request, user): return headed_redirect_response("account_inactive") def respond_email_verification_sent(self, request, user): return headed_redirect_response("account_email_verification_sent") def _get_login_attempts_cache_key(self, request, **credentials): site = get_current_site(request) login = credentials.get("email", credentials.get("username", "")).lower() return "{site}:{login}".format(site=site.domain, login=login) def _delete_login_attempts_cached_email(self, request, **credentials): cache_key = self._get_login_attempts_cache_key(request, **credentials) ratelimit.clear(request, action="login_failed", key=cache_key) def pre_authenticate(self, request, **credentials): cache_key = self._get_login_attempts_cache_key(request, **credentials) if not ratelimit.consume( request, action="login_failed", key=cache_key, ): raise self.validation_error("too_many_login_attempts") def authenticate(self, request, **credentials): """Only authenticates, does not actually login. See `login`""" from allauth.account.auth_backends import AuthenticationBackend self.pre_authenticate(request, **credentials) AuthenticationBackend.unstash_authenticated_user() user = authenticate(request, **credentials) alt_user = AuthenticationBackend.unstash_authenticated_user() user = user or alt_user if user: self._delete_login_attempts_cached_email(request, **credentials) else: self.authentication_failed(request, **credentials) return user def authentication_failed(self, request, **credentials): pass def reauthenticate(self, user, password): from allauth.account.models import EmailAddress from allauth.account.utils import user_username credentials = {"password": password} username = user_username(user) if username: credentials["username"] = username email = EmailAddress.objects.get_primary_email(user) if email: credentials["email"] = email reauth_user = self.authenticate(context.request, **credentials) return reauth_user is not None and reauth_user.pk == user.pk def is_ajax(self, request): return any( [ request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest", request.content_type == "application/json", request.META.get("HTTP_ACCEPT") == "application/json", ] ) def get_client_ip(self, request): x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR") if x_forwarded_for: ip = x_forwarded_for.split(",")[0] else: ip = request.META.get("REMOTE_ADDR") return ip def get_http_user_agent(self, request): return request.META.get("HTTP_USER_AGENT", "Unspecified") def generate_emailconfirmation_key(self, email): key = get_random_string(64).lower() return key def get_login_stages(self): ret = [] ret.append("allauth.account.stages.LoginByCodeStage") ret.append("allauth.account.stages.EmailVerificationStage") if allauth_app_settings.MFA_ENABLED: from allauth.mfa import app_settings as mfa_settings ret.append("allauth.mfa.stages.AuthenticateStage") if mfa_settings.PASSKEY_SIGNUP_ENABLED: ret.append("allauth.mfa.webauthn.stages.PasskeySignupStage") return ret def get_reauthentication_methods(self, user): """The order of the methods returned matters. The first method is the default when using the `@reauthentication_required` decorator. """ from allauth.account.internal.flows.reauthentication import ( get_reauthentication_flows, ) flow_by_id = {f["id"]: f for f in get_reauthentication_flows(user)} ret = [] if "reauthenticate" in flow_by_id: entry = { "id": "reauthenticate", "description": _("Use your password"), "url": reverse("account_reauthenticate"), } ret.append(entry) if "mfa_reauthenticate" in flow_by_id: types = flow_by_id["mfa_reauthenticate"]["types"] if "recovery_codes" in types or "totp" in types: entry = { "id": "mfa_reauthenticate", "description": _("Use authenticator app or code"), "url": reverse("mfa_reauthenticate"), } ret.append(entry) if "webauthn" in types: entry = { "id": "mfa_reauthenticate:webauthn", "description": _("Use a security key"), "url": reverse("mfa_reauthenticate_webauthn"), } ret.append(entry) return ret def send_notification_mail(self, template_prefix, user, context=None, email=None): from allauth.account.models import EmailAddress if not app_settings.EMAIL_NOTIFICATIONS: return if not email: email = EmailAddress.objects.get_primary_email(user) if not email: return ctx = { "timestamp": timezone.now(), "ip": self.get_client_ip(self.request), "user_agent": self.get_http_user_agent(self.request), } if context: ctx.update(context) self.send_mail(template_prefix, email, ctx) def generate_login_code(self) -> str: """ Generates a new login code. """ return self._generate_code() def generate_email_verification_code(self) -> str: """ Generates a new email verification code. """ return self._generate_code() def _generate_code(self): forbidden_chars = "0OI18B2ZAEU" allowed_chars = string.ascii_uppercase + string.digits for ch in forbidden_chars: allowed_chars = allowed_chars.replace(ch, "") return get_random_string(length=6, allowed_chars=allowed_chars) def is_login_by_code_required(self, login) -> bool: """ Returns whether or not login-by-code is required for the given login. """ from allauth.account import authentication method = None records = authentication.get_authentication_records(self.request) if records: method = records[-1]["method"] if method == "code": return False value = app_settings.LOGIN_BY_CODE_REQUIRED if isinstance(value, bool): return value if not value: return False return method is None or method in value def get_adapter(request=None): return import_attribute(app_settings.ADAPTER)(request) django-allauth-65.0.2/allauth/account/admin.py000066400000000000000000000022121467545753200212450ustar00rootroot00000000000000from django.contrib import admin from django.utils.translation import gettext_lazy as _ from . import app_settings from .adapter import get_adapter from .models import EmailAddress, EmailConfirmation class EmailAddressAdmin(admin.ModelAdmin): list_display = ("email", "user", "primary", "verified") list_filter = ("primary", "verified") search_fields = [] raw_id_fields = ("user",) actions = ["make_verified"] def get_search_fields(self, request): base_fields = get_adapter().get_user_search_fields() return ["email"] + list(map(lambda a: "user__" + a, base_fields)) def make_verified(self, request, queryset): queryset.update(verified=True) make_verified.short_description = _("Mark selected email addresses as verified") # type: ignore[attr-defined] class EmailConfirmationAdmin(admin.ModelAdmin): list_display = ("email_address", "created", "sent", "key") list_filter = ("sent",) raw_id_fields = ("email_address",) if not app_settings.EMAIL_CONFIRMATION_HMAC: admin.site.register(EmailConfirmation, EmailConfirmationAdmin) admin.site.register(EmailAddress, EmailAddressAdmin) django-allauth-65.0.2/allauth/account/app_settings.py000066400000000000000000000360521467545753200226660ustar00rootroot00000000000000import warnings from enum import Enum from typing import Set, Union from django.core.exceptions import ImproperlyConfigured class AppSettings: class AuthenticationMethod(str, Enum): USERNAME = "username" EMAIL = "email" USERNAME_EMAIL = "username_email" class EmailVerificationMethod(str, Enum): # After signing up, keep the user account inactive until the email # address is verified MANDATORY = "mandatory" # Allow login with unverified email (email verification is # still sent) OPTIONAL = "optional" # Don't send email verification mails during signup NONE = "none" def __init__(self, prefix): from django.conf import settings self.prefix = prefix # If login is by email, email must be required assert ( not self.AUTHENTICATION_METHOD == self.AuthenticationMethod.EMAIL ) or self.EMAIL_REQUIRED # If login includes email, login must be unique assert ( self.AUTHENTICATION_METHOD == self.AuthenticationMethod.USERNAME ) or self.UNIQUE_EMAIL assert ( self.EMAIL_VERIFICATION != self.EmailVerificationMethod.MANDATORY ) or self.EMAIL_REQUIRED if not self.USER_MODEL_USERNAME_FIELD: assert not self.USERNAME_REQUIRED assert self.AUTHENTICATION_METHOD not in ( self.AuthenticationMethod.USERNAME, self.AuthenticationMethod.USERNAME_EMAIL, ) if self.MAX_EMAIL_ADDRESSES is not None: assert self.MAX_EMAIL_ADDRESSES > 0 if self.CHANGE_EMAIL: if self.MAX_EMAIL_ADDRESSES is not None and self.MAX_EMAIL_ADDRESSES != 2: raise ImproperlyConfigured( "Invalid combination of ACCOUNT_CHANGE_EMAIL and ACCOUNT_MAX_EMAIL_ADDRESSES" ) if hasattr(settings, "ACCOUNT_LOGIN_ATTEMPTS_LIMIT") or hasattr( settings, "ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT" ): warnings.warn( "settings.ACCOUNT_LOGIN_ATTEMPTS_LIMIT/TIMEOUT is deprecated, use: settings.ACCOUNT_RATE_LIMITS['login_failed']" ) if hasattr(settings, "ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN"): warnings.warn( "settings.ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN is deprecated, use: settings.ACCOUNT_RATE_LIMITS['confirm_email']" ) def _setting(self, name, dflt): from allauth.utils import get_setting return get_setting(self.prefix + name, dflt) @property def PREVENT_ENUMERATION(self): return self._setting("PREVENT_ENUMERATION", True) @property def DEFAULT_HTTP_PROTOCOL(self): return self._setting("DEFAULT_HTTP_PROTOCOL", "http").lower() @property def EMAIL_CONFIRMATION_EXPIRE_DAYS(self): """ Determines the expiration date of email confirmation mails (# of days) """ from django.conf import settings return self._setting( "EMAIL_CONFIRMATION_EXPIRE_DAYS", getattr(settings, "EMAIL_CONFIRMATION_DAYS", 3), ) @property def EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL(self): """ The URL to redirect to after a successful email confirmation, in case of an authenticated user """ return self._setting("EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL", None) @property def EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL(self): """ The URL to redirect to after a successful email confirmation, in case no user is logged in """ from django.conf import settings return self._setting( "EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL", settings.LOGIN_URL ) @property def EMAIL_REQUIRED(self): """ The user is required to hand over an email address when signing up """ return self._setting("EMAIL_REQUIRED", False) @property def EMAIL_VERIFICATION(self): """ See email verification method """ ret = self._setting("EMAIL_VERIFICATION", self.EmailVerificationMethod.OPTIONAL) # Deal with legacy (boolean based) setting if ret is True: ret = self.EmailVerificationMethod.MANDATORY elif ret is False: ret = self.EmailVerificationMethod.OPTIONAL return self.EmailVerificationMethod(ret) @property def EMAIL_VERIFICATION_BY_CODE_ENABLED(self): return self._setting("EMAIL_VERIFICATION_BY_CODE_ENABLED", False) @property def EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS(self): return self._setting("EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS", 3) @property def EMAIL_VERIFICATION_BY_CODE_TIMEOUT(self): return self._setting("EMAIL_VERIFICATION_BY_CODE_TIMEOUT", 15 * 60) @property def MAX_EMAIL_ADDRESSES(self): return self._setting("MAX_EMAIL_ADDRESSES", None) @property def CHANGE_EMAIL(self): return self._setting("CHANGE_EMAIL", False) @property def AUTHENTICATION_METHOD(self): ret = self._setting("AUTHENTICATION_METHOD", self.AuthenticationMethod.USERNAME) return self.AuthenticationMethod(ret) @property def EMAIL_MAX_LENGTH(self): """ Adjust max_length of email addresses """ return self._setting("EMAIL_MAX_LENGTH", 254) @property def UNIQUE_EMAIL(self): """ Enforce uniqueness of email addresses """ return self._setting("UNIQUE_EMAIL", True) @property def SIGNUP_EMAIL_ENTER_TWICE(self): """ Signup email verification """ return self._setting("SIGNUP_EMAIL_ENTER_TWICE", False) @property def SIGNUP_PASSWORD_ENTER_TWICE(self): """ Signup password verification """ legacy = self._setting("SIGNUP_PASSWORD_VERIFICATION", True) return self._setting("SIGNUP_PASSWORD_ENTER_TWICE", legacy) @property def SIGNUP_REDIRECT_URL(self): from django.conf import settings return self._setting("SIGNUP_REDIRECT_URL", settings.LOGIN_REDIRECT_URL) @property def PASSWORD_MIN_LENGTH(self): """ Minimum password Length """ from django.conf import settings ret = None if not settings.AUTH_PASSWORD_VALIDATORS: ret = self._setting("PASSWORD_MIN_LENGTH", 6) return ret @property def RATE_LIMITS(self): rls = self._setting("RATE_LIMITS", {}) if rls is False: return {} attempts_amount = self._setting("LOGIN_ATTEMPTS_LIMIT", 5) attempts_timeout = self._setting("LOGIN_ATTEMPTS_TIMEOUT", 60 * 5) login_failed_rl = None if attempts_amount and attempts_timeout: login_failed_rl = f"10/m/ip,{attempts_amount}/{attempts_timeout}s/key" if self.EMAIL_VERIFICATION_BY_CODE_ENABLED: confirm_email_rl = "1/10s/key" else: cooldown = self._setting("EMAIL_CONFIRMATION_COOLDOWN", 3 * 60) confirm_email_rl = None if cooldown: confirm_email_rl = f"1/{cooldown}s/key" ret = { # Change password view (for users already logged in) "change_password": "5/m/user", # Email management (e.g. add, remove, change primary) "manage_email": "10/m/user", # Request a password reset, global rate limit per IP "reset_password": "20/m/ip,5/m/key", # Reauthentication for users already logged in "reauthenticate": "10/m/user", # Password reset (the view the password reset email links to). "reset_password_from_key": "20/m/ip", # Signups. "signup": "20/m/ip", # Logins. "login": "30/m/ip", # Request a login code: key is the email. "request_login_code": "20/m/ip,3/m/key", # Logins. "login_failed": login_failed_rl, # Confirm email "confirm_email": confirm_email_rl, } ret.update(rls) return ret @property def EMAIL_SUBJECT_PREFIX(self): """ Subject-line prefix to use for email messages sent """ return self._setting("EMAIL_SUBJECT_PREFIX", None) @property def SIGNUP_FORM_CLASS(self): """ Signup form """ return self._setting("SIGNUP_FORM_CLASS", None) @property def SIGNUP_FORM_HONEYPOT_FIELD(self): """ Honeypot field name. Empty string or ``None`` will disable honeypot behavior. """ return self._setting("SIGNUP_FORM_HONEYPOT_FIELD", None) @property def USERNAME_REQUIRED(self): """ The user is required to enter a username when signing up """ return self._setting("USERNAME_REQUIRED", True) @property def USERNAME_MIN_LENGTH(self): """ Minimum username Length """ return self._setting("USERNAME_MIN_LENGTH", 1) @property def USERNAME_BLACKLIST(self): """ List of usernames that are not allowed """ return self._setting("USERNAME_BLACKLIST", []) @property def PASSWORD_INPUT_RENDER_VALUE(self): """ render_value parameter as passed to PasswordInput fields """ return self._setting("PASSWORD_INPUT_RENDER_VALUE", False) @property def ADAPTER(self): return self._setting("ADAPTER", "allauth.account.adapter.DefaultAccountAdapter") @property def CONFIRM_EMAIL_ON_GET(self): return self._setting("CONFIRM_EMAIL_ON_GET", False) @property def AUTHENTICATED_LOGIN_REDIRECTS(self): return self._setting("AUTHENTICATED_LOGIN_REDIRECTS", True) @property def LOGIN_ON_EMAIL_CONFIRMATION(self): """ Automatically log the user in once they confirmed their email address """ return self._setting("LOGIN_ON_EMAIL_CONFIRMATION", False) @property def LOGIN_ON_PASSWORD_RESET(self): """ Automatically log the user in immediately after resetting their password. """ return self._setting("LOGIN_ON_PASSWORD_RESET", False) @property def LOGOUT_REDIRECT_URL(self): from django.conf import settings return self._setting("LOGOUT_REDIRECT_URL", settings.LOGOUT_REDIRECT_URL or "/") @property def LOGOUT_ON_GET(self): return self._setting("LOGOUT_ON_GET", False) @property def LOGOUT_ON_PASSWORD_CHANGE(self): return self._setting("LOGOUT_ON_PASSWORD_CHANGE", False) @property def USER_MODEL_USERNAME_FIELD(self): return self._setting("USER_MODEL_USERNAME_FIELD", "username") @property def USER_MODEL_EMAIL_FIELD(self): return self._setting("USER_MODEL_EMAIL_FIELD", "email") @property def SESSION_COOKIE_AGE(self): """ Deprecated -- use Django's settings.SESSION_COOKIE_AGE instead """ from django.conf import settings return self._setting("SESSION_COOKIE_AGE", settings.SESSION_COOKIE_AGE) @property def SESSION_REMEMBER(self): """ Controls the life time of the session. Set to `None` to ask the user ("Remember me?"), `False` to not remember, and `True` to always remember. """ return self._setting("SESSION_REMEMBER", None) @property def TEMPLATE_EXTENSION(self): """ A string defining the template extension to use, defaults to `html`. """ return self._setting("TEMPLATE_EXTENSION", "html") @property def FORMS(self): return self._setting("FORMS", {}) @property def EMAIL_CONFIRMATION_HMAC(self): return self._setting("EMAIL_CONFIRMATION_HMAC", True) @property def SALT(self): return self._setting("SALT", "account") @property def PRESERVE_USERNAME_CASING(self): return self._setting("PRESERVE_USERNAME_CASING", True) @property def USERNAME_VALIDATORS(self): from django.contrib.auth import get_user_model from django.core.exceptions import ImproperlyConfigured from allauth.utils import import_attribute path = self._setting("USERNAME_VALIDATORS", None) if path: ret = import_attribute(path) if not isinstance(ret, list): raise ImproperlyConfigured( "ACCOUNT_USERNAME_VALIDATORS is expected to be a list" ) else: if self.USER_MODEL_USERNAME_FIELD is not None: ret = ( get_user_model() ._meta.get_field(self.USER_MODEL_USERNAME_FIELD) .validators ) else: ret = [] return ret @property def PASSWORD_RESET_TOKEN_GENERATOR(self): from allauth.account.forms import EmailAwarePasswordResetTokenGenerator from allauth.utils import import_attribute token_generator_path = self._setting("PASSWORD_RESET_TOKEN_GENERATOR", None) if token_generator_path is not None: token_generator = import_attribute(token_generator_path) else: token_generator = EmailAwarePasswordResetTokenGenerator return token_generator @property def EMAIL_UNKNOWN_ACCOUNTS(self): return self._setting("EMAIL_UNKNOWN_ACCOUNTS", True) @property def REAUTHENTICATION_TIMEOUT(self): return self._setting("REAUTHENTICATION_TIMEOUT", 300) @property def EMAIL_NOTIFICATIONS(self): return self._setting("EMAIL_NOTIFICATIONS", False) @property def REAUTHENTICATION_REQUIRED(self): return self._setting("REAUTHENTICATION_REQUIRED", False) @property def LOGIN_BY_CODE_ENABLED(self): return self._setting("LOGIN_BY_CODE_ENABLED", False) @property def LOGIN_BY_CODE_MAX_ATTEMPTS(self): return self._setting("LOGIN_BY_CODE_MAX_ATTEMPTS", 3) @property def LOGIN_BY_CODE_TIMEOUT(self): return self._setting("LOGIN_BY_CODE_TIMEOUT", 3 * 60) @property def LOGIN_TIMEOUT(self): """ The maximum allowed time (in seconds) for a login to go through the various login stages. This limits, for example, the time span that the 2FA stage remains available. """ return self._setting("LOGIN_TIMEOUT", 15 * 60) @property def LOGIN_BY_CODE_REQUIRED(self) -> Union[bool, Set[str]]: """ When enabled (in case of ``True``), every user logging in is required to input a login confirmation code sent by email. Alternatively, you can specify a set of authentication methods (``"password"``, ``"mfa"``, or ``"socialaccount"``) for which login codes are required. """ value = self._setting("LOGIN_BY_CODE_REQUIRED", False) if isinstance(value, bool): return value return set(value) _app_settings = AppSettings("ACCOUNT_") def __getattr__(name): # See https://peps.python.org/pep-0562/ return getattr(_app_settings, name) django-allauth-65.0.2/allauth/account/apps.py000066400000000000000000000013131467545753200211210ustar00rootroot00000000000000from django.apps import AppConfig from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.translation import gettext_lazy as _ from allauth import app_settings class AccountConfig(AppConfig): name = "allauth.account" verbose_name = _("Accounts") default_auto_field = app_settings.DEFAULT_AUTO_FIELD or "django.db.models.AutoField" def ready(self): from allauth.account import checks # noqa required_mw = "allauth.account.middleware.AccountMiddleware" if required_mw not in settings.MIDDLEWARE: raise ImproperlyConfigured( f"{required_mw} must be added to settings.MIDDLEWARE" ) django-allauth-65.0.2/allauth/account/auth_backends.py000066400000000000000000000077121467545753200227620ustar00rootroot00000000000000from threading import local from django.contrib.auth import get_user_model from django.contrib.auth.backends import ModelBackend from . import app_settings from .app_settings import AuthenticationMethod from .utils import filter_users_by_email, filter_users_by_username _stash = local() class AuthenticationBackend(ModelBackend): def authenticate(self, request, **credentials): ret = None if app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.EMAIL: ret = self._authenticate_by_email(**credentials) elif app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.USERNAME_EMAIL: ret = self._authenticate_by_email(**credentials) if not ret: ret = self._authenticate_by_username(**credentials) else: ret = self._authenticate_by_username(**credentials) return ret def _authenticate_by_username(self, **credentials): username_field = app_settings.USER_MODEL_USERNAME_FIELD username = credentials.get("username") password = credentials.get("password") User = get_user_model() if not username_field or username is None or password is None: return None try: # Username query is case insensitive user = filter_users_by_username(username).get() except User.DoesNotExist: # Run the default password hasher once to reduce the timing # difference between an existing and a nonexistent user. get_user_model()().set_password(password) return None else: if self._check_password(user, password): return user def _authenticate_by_email(self, **credentials): # Even though allauth will pass along `email`, other apps may # not respect this setting. For example, when using # django-tastypie basic authentication, the login is always # passed as `username`. So let's play nice with other apps # and use username as fallback email = credentials.get("email", credentials.get("username")) if email: for user in filter_users_by_email(email, prefer_verified=True): if self._check_password(user, credentials["password"]): return user return None def _check_password(self, user, password): ret = user.check_password(password) if ret: ret = self.user_can_authenticate(user) if not ret: self._stash_user(user) return ret @classmethod def _stash_user(cls, user): """Now, be aware, the following is quite ugly, let me explain: Even if the user credentials match, the authentication can fail because Django's default ModelBackend calls user_can_authenticate(), which checks `is_active`. Now, earlier versions of allauth did not do this and simply returned the user as authenticated, even in case of `is_active=False`. For allauth scope, this does not pose a problem, as these users are properly redirected to an account inactive page. This does pose a problem when the allauth backend is used in a different context where allauth is not responsible for the login. Then, by not checking on `user_can_authenticate()` users will allow to become authenticated whereas according to Django logic this should not be allowed. In order to preserve the allauth behavior while respecting Django's logic, we stash a user for which the password check succeeded but `user_can_authenticate()` failed. In the allauth authentication logic, we can then unstash this user and proceed pointing the user to the account inactive page. """ global _stash ret = getattr(_stash, "user", None) _stash.user = user return ret @classmethod def unstash_authenticated_user(cls): return cls._stash_user(None) django-allauth-65.0.2/allauth/account/authentication.py000066400000000000000000000003171467545753200232000ustar00rootroot00000000000000from allauth.account.internal.flows.login import ( AUTHENTICATION_METHODS_SESSION_KEY, ) def get_authentication_records(request): return request.session.get(AUTHENTICATION_METHODS_SESSION_KEY, []) django-allauth-65.0.2/allauth/account/checks.py000066400000000000000000000033171467545753200214240ustar00rootroot00000000000000from django.core.checks import Critical, Warning, register @register() def adapter_check(app_configs, **kwargs): from allauth.account.adapter import get_adapter ret = [] adapter = get_adapter() if hasattr(adapter, "get_email_confirmation_redirect_url"): ret.append( Warning( msg="adapter.get_email_confirmation_redirect_url(request) is deprecated, use adapter.get_email_verification_redirect_url(email_address)" ) ) return ret @register() def settings_check(app_configs, **kwargs): from allauth import app_settings as allauth_app_settings from allauth.account import app_settings ret = [] if allauth_app_settings.SOCIALACCOUNT_ONLY: if app_settings.LOGIN_BY_CODE_ENABLED: ret.append( Critical( msg="SOCIALACCOUNT_ONLY does not work with ACCOUNT_LOGIN_BY_CODE_ENABLED" ) ) if allauth_app_settings.MFA_ENABLED: ret.append( Critical(msg="SOCIALACCOUNT_ONLY does not work with 'allauth.mfa'") ) if app_settings.EMAIL_VERIFICATION != app_settings.EmailVerificationMethod.NONE: ret.append( Critical( msg="SOCIALACCOUNT_ONLY requires ACCOUNT_EMAIL_VERIFICATION = 'none'" ) ) if ( app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED and app_settings.EMAIL_VERIFICATION != app_settings.EmailVerificationMethod.MANDATORY ): ret.append( Critical( msg="ACCOUNT_EMAIL_VERFICATION_BY_CODE requires ACCOUNT_EMAIL_VERIFICATION = 'mandatory'" ) ) return ret django-allauth-65.0.2/allauth/account/decorators.py000066400000000000000000000071011467545753200223240ustar00rootroot00000000000000from functools import wraps from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.http import HttpResponseRedirect from django.shortcuts import render, resolve_url from allauth.account.internal.flows import reauthentication from allauth.account.models import EmailAddress from allauth.account.utils import ( get_next_redirect_url, send_email_confirmation, ) from allauth.core.exceptions import ReauthenticationRequired from allauth.core.internal import httpkit def verified_email_required( function=None, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME ): """ Even when email verification is not mandatory during signup, there may be circumstances during which you really want to prevent unverified users to proceed. This decorator ensures the user is authenticated and has a verified email address. If the former is not the case then the behavior is identical to that of the standard `login_required` decorator. If the latter does not hold, email verification mails are automatically resend and the user is presented with a page informing them they needs to verify their email address. """ def decorator(view_func): @login_required(redirect_field_name=redirect_field_name, login_url=login_url) def _wrapped_view(request, *args, **kwargs): if not EmailAddress.objects.filter( user=request.user, verified=True ).exists(): send_email_confirmation(request, request.user) return render(request, "account/verified_email_required.html") return view_func(request, *args, **kwargs) return _wrapped_view if function: return decorator(function) return decorator def reauthentication_required( function=None, redirect_field_name=REDIRECT_FIELD_NAME, allow_get=False, enabled=None, ): def decorator(view_func): @wraps(view_func) def _wrapper_view(request, *args, **kwargs): pass_method = allow_get and request.method == "GET" ena = (enabled is None) or ( enabled(request) if callable(enabled) else enabled ) if ena and not pass_method: if ( request.user.is_anonymous or not reauthentication.did_recently_authenticate(request) ): raise ReauthenticationRequired() return view_func(request, *args, **kwargs) return _wrapper_view if function: return decorator(function) return decorator def secure_admin_login(function=None): def decorator(view_func): @wraps(view_func) def _wrapper_view(request, *args, **kwargs): if request.user.is_authenticated: if not request.user.is_staff or not request.user.is_active: raise PermissionDenied() return view_func(request, *args, **kwargs) else: next_url = get_next_redirect_url(request) if not next_url: next_url = request.get_full_path() login_url = resolve_url(settings.LOGIN_URL) login_url = httpkit.add_query_params( login_url, {REDIRECT_FIELD_NAME: next_url} ) return HttpResponseRedirect(login_url) return _wrapper_view if function: return decorator(function) return decorator django-allauth-65.0.2/allauth/account/forms.py000066400000000000000000000652531467545753200213210ustar00rootroot00000000000000from importlib import import_module from django import forms from django.contrib.auth import get_user_model, password_validation from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.core import exceptions, validators from django.urls import NoReverseMatch, reverse from django.utils.safestring import mark_safe from django.utils.translation import gettext, gettext_lazy as _, pgettext from allauth.account.internal import flows from allauth.account.internal.stagekit import LOGIN_SESSION_KEY from allauth.account.stages import EmailVerificationStage from allauth.core import context, ratelimit from allauth.utils import get_username_max_length, set_form_field_order from . import app_settings from .adapter import DefaultAccountAdapter, get_adapter from .app_settings import AuthenticationMethod from .models import EmailAddress, Login from .utils import ( filter_users_by_email, setup_user_email, sync_user_email_addresses, url_str_to_user_pk, user_email, user_pk_to_url_str, user_username, ) class EmailAwarePasswordResetTokenGenerator(PasswordResetTokenGenerator): def _make_hash_value(self, user, timestamp): ret = super(EmailAwarePasswordResetTokenGenerator, self)._make_hash_value( user, timestamp ) sync_user_email_addresses(user) email = user_email(user) emails = set([email] if email else []) emails.update( EmailAddress.objects.filter(user=user).values_list("email", flat=True) ) ret += "|".join(sorted(emails)) return ret default_token_generator = app_settings.PASSWORD_RESET_TOKEN_GENERATOR() class PasswordVerificationMixin: def clean(self): cleaned_data = super(PasswordVerificationMixin, self).clean() password1 = cleaned_data.get("password1") password2 = cleaned_data.get("password2") if (password1 and password2) and password1 != password2: self.add_error("password2", _("You must type the same password each time.")) return cleaned_data class PasswordField(forms.CharField): def __init__(self, *args, **kwargs): render_value = kwargs.pop( "render_value", app_settings.PASSWORD_INPUT_RENDER_VALUE ) kwargs["widget"] = forms.PasswordInput( render_value=render_value, attrs={"placeholder": kwargs.get("label")}, ) autocomplete = kwargs.pop("autocomplete", None) if autocomplete is not None: kwargs["widget"].attrs["autocomplete"] = autocomplete super(PasswordField, self).__init__(*args, **kwargs) class SetPasswordField(PasswordField): def __init__(self, *args, **kwargs): kwargs["autocomplete"] = "new-password" kwargs.setdefault( "help_text", password_validation.password_validators_help_text_html() ) super().__init__(*args, **kwargs) self.user = None def clean(self, value): value = super().clean(value) value = get_adapter().clean_password(value, user=self.user) return value class LoginForm(forms.Form): password = PasswordField(label=_("Password"), autocomplete="current-password") remember = forms.BooleanField(label=_("Remember Me"), required=False) user = None def __init__(self, *args, **kwargs): self.request = kwargs.pop("request", None) super(LoginForm, self).__init__(*args, **kwargs) if app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.EMAIL: login_widget = forms.EmailInput( attrs={ "placeholder": _("Email address"), "autocomplete": "email", } ) login_field = forms.EmailField(label=_("Email"), widget=login_widget) elif app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.USERNAME: login_widget = forms.TextInput( attrs={"placeholder": _("Username"), "autocomplete": "username"} ) login_field = forms.CharField( label=_("Username"), widget=login_widget, max_length=get_username_max_length(), ) else: assert ( app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.USERNAME_EMAIL ) login_widget = forms.TextInput( attrs={"placeholder": _("Username or email"), "autocomplete": "email"} ) login_field = forms.CharField( label=pgettext("field label", "Login"), widget=login_widget ) self.fields["login"] = login_field set_form_field_order(self, ["login", "password", "remember"]) if app_settings.SESSION_REMEMBER is not None: del self.fields["remember"] try: reset_url = reverse("account_reset_password") except NoReverseMatch: pass else: forgot_txt = _("Forgot your password?") self.fields["password"].help_text = mark_safe( f'{forgot_txt}' ) def user_credentials(self): """ Provides the credentials required to authenticate the user for login. """ credentials = {} login = self.cleaned_data["login"] if app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.EMAIL: credentials["email"] = login elif app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.USERNAME: credentials["username"] = login else: if self._is_login_email(login): credentials["email"] = login credentials["username"] = login credentials["password"] = self.cleaned_data["password"] return credentials def clean_login(self): login = self.cleaned_data["login"] return login.strip() def _is_login_email(self, login): try: validators.validate_email(login) ret = True except exceptions.ValidationError: ret = False return ret def clean(self): super(LoginForm, self).clean() if self._errors: return credentials = self.user_credentials() adapter = get_adapter(self.request) user = adapter.authenticate(self.request, **credentials) if user: login = Login(user=user, email=credentials.get("email")) if flows.login.is_login_rate_limited(context.request, login): raise adapter.validation_error("too_many_login_attempts") self._login = login self.user = user else: auth_method = app_settings.AUTHENTICATION_METHOD if auth_method == app_settings.AuthenticationMethod.USERNAME_EMAIL: login = self.cleaned_data["login"] if self._is_login_email(login): auth_method = app_settings.AuthenticationMethod.EMAIL else: auth_method = app_settings.AuthenticationMethod.USERNAME raise adapter.validation_error("%s_password_mismatch" % auth_method.value) return self.cleaned_data def login(self, request, redirect_url=None): credentials = self.user_credentials() login = self._login login.redirect_url = redirect_url ret = flows.login.perform_password_login(request, credentials, login) remember = app_settings.SESSION_REMEMBER if remember is None: remember = self.cleaned_data["remember"] if remember: request.session.set_expiry(app_settings.SESSION_COOKIE_AGE) else: request.session.set_expiry(0) return ret class _DummyCustomSignupForm(forms.Form): def signup(self, request, user): """ Invoked at signup time to complete the signup of the user. """ pass def _base_signup_form_class(): """ Currently, we inherit from the custom form, if any. This is all not very elegant, though it serves a purpose: - There are two signup forms: one for local accounts, and one for social accounts - Both share a common base (BaseSignupForm) - Given the above, how to put in a custom signup form? Which form would your custom form derive from, the local or the social one? """ if not app_settings.SIGNUP_FORM_CLASS: return _DummyCustomSignupForm try: fc_module, fc_classname = app_settings.SIGNUP_FORM_CLASS.rsplit(".", 1) except ValueError: raise exceptions.ImproperlyConfigured( "%s does not point to a form class" % app_settings.SIGNUP_FORM_CLASS ) try: mod = import_module(fc_module) except ImportError as e: raise exceptions.ImproperlyConfigured( "Error importing form class %s:" ' "%s"' % (fc_module, e) ) try: fc_class = getattr(mod, fc_classname) except AttributeError: raise exceptions.ImproperlyConfigured( 'Module "%s" does not define a' ' "%s" class' % (fc_module, fc_classname) ) if not hasattr(fc_class, "signup"): raise exceptions.ImproperlyConfigured( "The custom signup form must offer" " a `def signup(self, request, user)` method", ) return fc_class class BaseSignupForm(_base_signup_form_class()): # type: ignore[misc] username = forms.CharField( label=_("Username"), min_length=app_settings.USERNAME_MIN_LENGTH, widget=forms.TextInput( attrs={"placeholder": _("Username"), "autocomplete": "username"} ), ) email = forms.EmailField( widget=forms.TextInput( attrs={ "type": "email", "placeholder": _("Email address"), "autocomplete": "email", } ) ) def __init__(self, *args, **kwargs): email_required = kwargs.pop("email_required", app_settings.EMAIL_REQUIRED) self.username_required = kwargs.pop( "username_required", app_settings.USERNAME_REQUIRED ) self.account_already_exists = False super(BaseSignupForm, self).__init__(*args, **kwargs) username_field = self.fields["username"] username_field.max_length = get_username_max_length() username_field.validators.append( validators.MaxLengthValidator(username_field.max_length) ) username_field.widget.attrs["maxlength"] = str(username_field.max_length) default_field_order = [ "email", "email2", # ignored when not present "username", "password1", "password2", # ignored when not present ] if app_settings.SIGNUP_EMAIL_ENTER_TWICE: self.fields["email2"] = forms.EmailField( label=_("Email (again)"), widget=forms.TextInput( attrs={ "type": "email", "placeholder": _("Email address confirmation"), } ), ) if email_required: self.fields["email"].label = gettext("Email") self.fields["email"].required = True else: self.fields["email"].label = gettext("Email (optional)") self.fields["email"].required = False self.fields["email"].widget.is_required = False if self.username_required: default_field_order = [ "username", "email", "email2", # ignored when not present "password1", "password2", # ignored when not present ] if not self.username_required: del self.fields["username"] set_form_field_order( self, getattr(self, "field_order", None) or default_field_order ) def clean_username(self): value = self.cleaned_data["username"] value = get_adapter().clean_username(value) # Note regarding preventing enumeration: if the username is already # taken, but the email address is not, we would still leak information # if we were to send an email to that email address stating that the # username is already in use. return value def clean_email(self): value = self.cleaned_data["email"].lower() value = get_adapter().clean_email(value) if value and app_settings.UNIQUE_EMAIL: value = self.validate_unique_email(value) return value def clean_email2(self): value = self.cleaned_data["email2"].lower() return value def validate_unique_email(self, value): adapter = get_adapter() assessment = flows.manage_email.assess_unique_email(value) if assessment is True: # All good. pass elif assessment is False: # Fail right away. raise adapter.validation_error("email_taken") else: assert assessment is None self.account_already_exists = True return adapter.validate_unique_email(value) def clean(self): cleaned_data = super(BaseSignupForm, self).clean() if app_settings.SIGNUP_EMAIL_ENTER_TWICE: email = cleaned_data.get("email") email2 = cleaned_data.get("email2") if (email and email2) and email != email2: self.add_error("email2", _("You must type the same email each time.")) return cleaned_data def custom_signup(self, request, user): self.signup(request, user) def try_save(self, request): """Try and save the user. This can fail in case of a conflict on the email address, in that case we will send an "account already exists" email and return a standard "email verification sent" response. """ if self.account_already_exists: # Don't create a new account, only send an email informing the user # that (s)he already has one... email = self.cleaned_data["email"] resp = flows.signup.prevent_enumeration(request, email) user = None # Fake a login stage. request.session[LOGIN_SESSION_KEY] = EmailVerificationStage.key else: user = self.save(request) resp = None return user, resp def save(self, request): email = self.cleaned_data.get("email") if self.account_already_exists: raise ValueError(email) adapter = get_adapter() user = adapter.new_user(request) adapter.save_user(request, user, self) self.custom_signup(request, user) # TODO: Move into adapter `save_user` ? setup_user_email(request, user, [EmailAddress(email=email)] if email else []) return user class SignupForm(BaseSignupForm): def __init__(self, *args, **kwargs): self.by_passkey = kwargs.pop("by_passkey", False) super(SignupForm, self).__init__(*args, **kwargs) if not self.by_passkey: self.fields["password1"] = PasswordField( label=_("Password"), autocomplete="new-password", help_text=password_validation.password_validators_help_text_html(), ) if app_settings.SIGNUP_PASSWORD_ENTER_TWICE: self.fields["password2"] = PasswordField( label=_("Password (again)"), autocomplete="new-password" ) if hasattr(self, "field_order"): set_form_field_order(self, self.field_order) honeypot_field_name = app_settings.SIGNUP_FORM_HONEYPOT_FIELD if honeypot_field_name: self.fields[honeypot_field_name] = forms.CharField( required=False, label="", widget=forms.TextInput( attrs={ "style": "position: absolute; right: -99999px;", "tabindex": "-1", "autocomplete": "nope", } ), ) def try_save(self, request): """ override of parent class method that adds additional catching of a potential bot filling out the honeypot field and returns a 'fake' email verification response if honeypot was filled out """ honeypot_field_name = app_settings.SIGNUP_FORM_HONEYPOT_FIELD if honeypot_field_name: if self.cleaned_data[honeypot_field_name]: user = None adapter = get_adapter() # honeypot fields work best when you do not report to the bot # that anything went wrong. So we return a fake email verification # sent response but without creating a user resp = adapter.respond_email_verification_sent(request, None) return user, resp return super().try_save(request) def clean(self): super().clean() # `password` cannot be of type `SetPasswordField`, as we don't # have a `User` yet. So, let's populate a dummy user to be used # for password validation. User = get_user_model() dummy_user = User() user_username(dummy_user, self.cleaned_data.get("username")) user_email(dummy_user, self.cleaned_data.get("email")) password = self.cleaned_data.get("password1") if password: try: get_adapter().clean_password(password, user=dummy_user) except forms.ValidationError as e: self.add_error("password1", e) if ( app_settings.SIGNUP_PASSWORD_ENTER_TWICE and "password1" in self.cleaned_data and "password2" in self.cleaned_data ): if self.cleaned_data["password1"] != self.cleaned_data["password2"]: self.add_error( "password2", _("You must type the same password each time."), ) return self.cleaned_data class UserForm(forms.Form): def __init__(self, user=None, *args, **kwargs): self.user = user super(UserForm, self).__init__(*args, **kwargs) class AddEmailForm(UserForm): email = forms.EmailField( label=_("Email"), required=True, widget=forms.TextInput( attrs={"type": "email", "placeholder": _("Email address")} ), ) def clean_email(self): from allauth.account import signals value = self.cleaned_data["email"].lower() adapter = get_adapter() value = adapter.clean_email(value) users = filter_users_by_email(value) on_this_account = [u for u in users if u.pk == self.user.pk] on_diff_account = [u for u in users if u.pk != self.user.pk] if on_this_account: raise adapter.validation_error("duplicate_email") if ( # Email is taken by a different account... on_diff_account # We care about not having duplicate emails and app_settings.UNIQUE_EMAIL # Enumeration prevention is turned off. and (not app_settings.PREVENT_ENUMERATION) ): raise adapter.validation_error("email_taken") if not EmailAddress.objects.can_add_email(self.user): raise adapter.validation_error( "max_email_addresses", app_settings.MAX_EMAIL_ADDRESSES ) signals._add_email.send( sender=self.user.__class__, email=value, user=self.user, ) return value def save(self, request): if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: email_address = EmailAddress( user=self.user, email=self.cleaned_data["email"] ) email_address.send_confirmation(request) return email_address elif app_settings.CHANGE_EMAIL: return EmailAddress.objects.add_new_email( request, self.user, self.cleaned_data["email"] ) return EmailAddress.objects.add_email( request, self.user, self.cleaned_data["email"], confirm=True ) class ChangePasswordForm(PasswordVerificationMixin, UserForm): oldpassword = PasswordField( label=_("Current Password"), autocomplete="current-password" ) password1 = SetPasswordField(label=_("New Password")) password2 = PasswordField(label=_("New Password (again)")) def __init__(self, *args, **kwargs): super(ChangePasswordForm, self).__init__(*args, **kwargs) self.fields["password1"].user = self.user def clean_oldpassword(self): if not self.user.check_password(self.cleaned_data.get("oldpassword")): raise get_adapter().validation_error("enter_current_password") return self.cleaned_data["oldpassword"] def save(self): flows.password_change.change_password(self.user, self.cleaned_data["password1"]) class SetPasswordForm(PasswordVerificationMixin, UserForm): password1 = SetPasswordField(label=_("Password")) password2 = PasswordField(label=_("Password (again)")) def __init__(self, *args, **kwargs): super(SetPasswordForm, self).__init__(*args, **kwargs) self.fields["password1"].user = self.user def save(self): flows.password_change.change_password(self.user, self.cleaned_data["password1"]) class ResetPasswordForm(forms.Form): email = forms.EmailField( label=_("Email"), required=True, widget=forms.TextInput( attrs={ "type": "email", "placeholder": _("Email address"), "autocomplete": "email", } ), ) def clean_email(self): email = self.cleaned_data["email"].lower() email = get_adapter().clean_email(email) self.users = filter_users_by_email(email, is_active=True, prefer_verified=True) if not self.users and not app_settings.PREVENT_ENUMERATION: raise get_adapter().validation_error("unknown_email") return self.cleaned_data["email"] def save(self, request, **kwargs) -> str: email = self.cleaned_data["email"] if not self.users: flows.signup.send_unknown_account_mail(request, email) return email adapter: DefaultAccountAdapter = get_adapter() token_generator = kwargs.get("token_generator", default_token_generator) for user in self.users: temp_key = token_generator.make_token(user) # send the password reset email uid = user_pk_to_url_str(user) # We intentionally pass an opaque `key` on the interface here, and # not implementation details such as a separate `uidb36` and # `key. Ideally, this should have done on `urls` level as well. key = f"{uid}-{temp_key}" url = adapter.get_reset_password_from_key_url(key) context = { "user": user, "password_reset_url": url, "uid": uid, "key": temp_key, "request": request, } if app_settings.AUTHENTICATION_METHOD != AuthenticationMethod.EMAIL: context["username"] = user_username(user) adapter.send_password_reset_mail(user, email, context) return email class ResetPasswordKeyForm(PasswordVerificationMixin, forms.Form): password1 = SetPasswordField(label=_("New Password")) password2 = PasswordField(label=_("New Password (again)")) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user", None) self.temp_key = kwargs.pop("temp_key", None) super(ResetPasswordKeyForm, self).__init__(*args, **kwargs) self.fields["password1"].user = self.user def save(self): flows.password_reset.reset_password(self.user, self.cleaned_data["password1"]) class UserTokenForm(forms.Form): uidb36 = forms.CharField() key = forms.CharField() reset_user = None token_generator = default_token_generator def _get_user(self, uidb36): User = get_user_model() try: pk = url_str_to_user_pk(uidb36) return User.objects.get(pk=pk) except (ValueError, User.DoesNotExist): return None def clean(self): cleaned_data = super(UserTokenForm, self).clean() uidb36 = cleaned_data.get("uidb36", None) key = cleaned_data.get("key", None) adapter = get_adapter() if not key: raise adapter.validation_error("invalid_password_reset") self.reset_user = self._get_user(uidb36) if self.reset_user is None or not self.token_generator.check_token( self.reset_user, key ): raise adapter.validation_error("invalid_password_reset") return cleaned_data class ReauthenticateForm(forms.Form): password = PasswordField(label=_("Password"), autocomplete="current-password") def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) def clean_password(self): password = self.cleaned_data.get("password") if not get_adapter().reauthenticate(self.user, password): raise get_adapter().validation_error("incorrect_password") return password class RequestLoginCodeForm(forms.Form): email = forms.EmailField( widget=forms.EmailInput( attrs={ "placeholder": _("Email address"), "autocomplete": "email", } ) ) def clean_email(self): adapter = get_adapter() email = self.cleaned_data["email"] if not app_settings.PREVENT_ENUMERATION: users = filter_users_by_email(email, is_active=True, prefer_verified=True) if not users: raise adapter.validation_error("unknown_email") if not ratelimit.consume( context.request, action="request_login_code", key=email.lower() ): raise adapter.validation_error("too_many_login_attempts") return email class BaseConfirmCodeForm(forms.Form): code = forms.CharField( label=_("Code"), widget=forms.TextInput( attrs={"placeholder": _("Code"), "autocomplete": "one-time-code"}, ), ) def __init__(self, *args, **kwargs): self.code = kwargs.pop("code") super().__init__(*args, **kwargs) def clean_code(self): code = self.cleaned_data.get("code") if not flows.login_by_code.compare_code(actual=code, expected=self.code): raise get_adapter().validation_error("incorrect_code") return code class ConfirmLoginCodeForm(BaseConfirmCodeForm): pass class ConfirmEmailVerificationCodeForm(BaseConfirmCodeForm): pass django-allauth-65.0.2/allauth/account/internal/000077500000000000000000000000001467545753200214225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/internal/__init__.py000066400000000000000000000001011467545753200235230ustar00rootroot00000000000000from allauth.account.internal import flows __all__ = ["flows"] django-allauth-65.0.2/allauth/account/internal/decorators.py000066400000000000000000000021761467545753200241470ustar00rootroot00000000000000from functools import wraps from django.contrib.auth import decorators from django.http import HttpResponseRedirect from django.urls import reverse from django.views.decorators.cache import never_cache from allauth.account.stages import LoginStageController from allauth.account.utils import get_login_redirect_url def _dummy_login_not_required(view_func): return view_func login_not_required = getattr( decorators, "login_not_required", _dummy_login_not_required ) def login_stage_required(stage: str, redirect_urlname: str): def decorator(view_func): @never_cache @login_not_required @wraps(view_func) def _wrapper_view(request, *args, **kwargs): if request.user.is_authenticated: return HttpResponseRedirect(get_login_redirect_url(request)) login_stage = LoginStageController.enter(request, stage) if not login_stage: return HttpResponseRedirect(reverse(redirect_urlname)) request._login_stage = login_stage return view_func(request, *args, **kwargs) return _wrapper_view return decorator django-allauth-65.0.2/allauth/account/internal/flows/000077500000000000000000000000001467545753200225545ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/internal/flows/__init__.py000066400000000000000000000007211467545753200246650ustar00rootroot00000000000000from allauth.account.internal.flows import ( email_verification, email_verification_by_code, login, login_by_code, logout, manage_email, password_change, password_reset, reauthentication, signup, ) __all__ = [ "password_reset", "password_change", "email_verification", "email_verification_by_code", "login", "login_by_code", "logout", "signup", "manage_email", "reauthentication", ] django-allauth-65.0.2/allauth/account/internal/flows/email_verification.py000066400000000000000000000224041467545753200267610ustar00rootroot00000000000000from typing import Optional, Tuple from django.contrib import messages from django.http import HttpRequest, HttpResponse from django.urls import reverse from allauth.account import app_settings, signals from allauth.account.adapter import get_adapter from allauth.account.internal.flows.manage_email import emit_email_changed from allauth.account.models import EmailAddress, Login from allauth.core import ratelimit from allauth.core.exceptions import ImmediateHttpResponse from allauth.core.internal.httpkit import get_frontend_url from allauth.utils import build_absolute_uri def verify_email_indirectly(request: HttpRequest, user, email: str) -> bool: try: email_address = EmailAddress.objects.get_for_user(user, email) except EmailAddress.DoesNotExist: return False else: if not email_address.verified: return verify_email(request, email_address) return True def verify_email_and_resume( request: HttpRequest, verification ) -> Tuple[Optional[EmailAddress], Optional[HttpResponse]]: email_address = verification.confirm(request) if not email_address: return None, None response = login_on_verification(request, verification) return email_address, response def verify_email(request: HttpRequest, email_address: EmailAddress) -> bool: """ Marks the email address as confirmed on the db """ added = not email_address.pk from_email_address = ( EmailAddress.objects.filter(user_id=email_address.user_id) .exclude(pk=email_address.pk) .first() ) if not email_address.set_verified(commit=False): get_adapter(request).add_message( request, messages.ERROR, "account/messages/email_confirmation_failed.txt", {"email": email_address.email}, ) return False email_address.set_as_primary(conditional=(not app_settings.CHANGE_EMAIL)) email_address.save() if added: signals.email_added.send( sender=EmailAddress, request=request, user=request.user, email_address=email_address, ) signals.email_confirmed.send( sender=EmailAddress, request=request, email_address=email_address, ) if app_settings.CHANGE_EMAIL: for instance in EmailAddress.objects.filter( user_id=email_address.user_id ).exclude(pk=email_address.pk): instance.remove() emit_email_changed(request, from_email_address, email_address) get_adapter(request).add_message( request, messages.SUCCESS, "account/messages/email_confirmed.txt", {"email": email_address.email}, ) return True def get_email_verification_url(request: HttpRequest, emailconfirmation) -> str: """Constructs the email confirmation (activation) url. Note that if you have architected your system such that email confirmations are sent outside of the request context `request` can be `None` here. """ url = get_frontend_url(request, "account_confirm_email", key=emailconfirmation.key) if not url: url = reverse("account_confirm_email", args=[emailconfirmation.key]) url = build_absolute_uri(request, url) return url def login_on_verification(request, verification) -> Optional[HttpResponse]: """Simply logging in the user may become a security issue. If you do not take proper care (e.g. don't purge used email confirmations), a malicious person that got hold of the link will be able to login over and over again and the user is unable to do anything about it. Even restoring their own mailbox security will not help, as the links will still work. For password reset this is different, this mechanism works only as long as the attacker has access to the mailbox. If they no longer has access they cannot issue a password request and intercept it. Furthermore, all places where the links are listed (log files, but even Google Analytics) all of a sudden need to be secured. Purging the email confirmation once confirmed changes the behavior -- users will not be able to repeatedly confirm (in case they forgot that they already clicked the mail). All in all, we only login on verification when the user that is in the process of signing up is present in the session to avoid all of the above. This may not 100% work in case the user closes the browser (and the session gets lost), but at least we're secure. """ from allauth.account.stages import ( EmailVerificationStage, LoginStageController, ) if not app_settings.LOGIN_ON_EMAIL_CONFIRMATION: return None if request.user.is_authenticated: return None stage = LoginStageController.enter(request, EmailVerificationStage.key) if not stage or not stage.login.user: return None if stage.login.user.pk != verification.email_address.user_id: return None return stage.exit() def consume_email_verification_rate_limit( request: HttpRequest, email: str, dry_run: bool = False ) -> bool: return ratelimit.consume( request, action="confirm_email", key=email.lower(), dry_run=dry_run ) def handle_verification_email_rate_limit(request, email: str) -> bool: """ For email verification by link, it is not an issue if the user runs into rate limits. The reason is that the link is session independent. Therefore, if the user hits rate limits, we can just silently skip sending additional verification emails, as the previous emails that were already sent still contain valid links. This is different from email verification by code. Here, the session contains a specific code, meaning, silently skipping new verification emails is not an option, and we must hard fail (429) instead. The latter was missing, fixed. """ rl_ok = consume_email_verification_rate_limit(request, email) if not rl_ok and app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: raise ImmediateHttpResponse(ratelimit.respond_429(request)) return rl_ok def send_verification_email(request, user, signup=False, email=None) -> bool: """ Email verification mails are sent: a) Explicitly: when a user signs up b) Implicitly: when a user attempts to log in using an unverified email while EMAIL_VERIFICATION is mandatory. Especially in case of b), we want to limit the number of mails sent (consider a user retrying a few times), which is why there is a cooldown period before sending a new mail. This cooldown period can be configured in ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN setting. TODO: This code is doing way too much. Looking up EmailAddress, creating if not present, etc. To be refactored. """ from allauth.account.utils import user_email adapter = get_adapter() sent = False email_address = None if not email: email = user_email(user) if not email: email_address = ( EmailAddress.objects.filter(user=user).order_by("verified", "pk").first() ) if email_address: email = email_address.email if email: if email_address is None: try: email_address = EmailAddress.objects.get_for_user(user, email) except EmailAddress.DoesNotExist: pass if email_address is not None: if not email_address.verified: send_email = handle_verification_email_rate_limit( request, email_address.email ) if send_email: send_email = adapter.should_send_confirmation_mail( request, email_address, signup ) if send_email: email_address.send_confirmation(request, signup=signup) sent = True else: send_email = False else: send_email = True email_address = EmailAddress.objects.add_email( request, user, email, signup=signup, confirm=True ) sent = True assert email_address # At this point, if we were supposed to send an email we have sent it. if send_email: adapter.add_message( request, messages.INFO, "account/messages/email_confirmation_sent.txt", {"email": email, "login": not signup, "signup": signup}, ) return sent def is_verification_rate_limited(request: HttpRequest, login: Login) -> bool: """ Returns whether or not the email verification is *hard* rate limited. Hard, meaning, it would be blocking login (verification by code, not link). """ if ( (not login.email) or (not app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED) or login.email_verification != app_settings.EmailVerificationMethod.MANDATORY ): return False try: email_address = EmailAddress.objects.get_for_user(login.user, login.email) if not email_address.verified: if not consume_email_verification_rate_limit( request, login.email, dry_run=True ): return True except EmailAddress.DoesNotExist: pass return False django-allauth-65.0.2/allauth/account/internal/flows/email_verification_by_code.py000066400000000000000000000071631467545753200304520ustar00rootroot00000000000000import time from typing import Any, Dict, Optional, Tuple from django.contrib.auth import get_user_model from django.http import HttpRequest from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.internal.flows.login_by_code import compare_code from allauth.account.internal.stagekit import clear_login from allauth.account.models import EmailAddress, EmailConfirmationMixin from allauth.core import context EMAIL_VERIFICATION_CODE_SESSION_KEY = "account_email_verification_code" class EmailVerificationModel(EmailConfirmationMixin): def __init__(self, email_address: EmailAddress, key: Optional[str] = None): self.email_address = email_address if not key: key = request_email_verification_code( context.request, user=email_address.user, email=email_address.email ) self.key = key @classmethod def create(cls, email_address: EmailAddress): return EmailVerificationModel(email_address) @classmethod def from_key(cls, key): verification, _ = get_pending_verification(context.request, peek=True) if not verification or not compare_code(actual=key, expected=verification.key): return None return verification def key_expired(self): return False def clear_state(request): request.session.pop(EMAIL_VERIFICATION_CODE_SESSION_KEY, None) clear_login(request) def request_email_verification_code( request: HttpRequest, user, email: str, ) -> str: code = "" pending_verification = { "at": time.time(), "failed_attempts": 0, "email": email, } pretend = user is None if not pretend: adapter = get_adapter() code = adapter.generate_email_verification_code() assert user._meta.pk pending_verification.update( { "user_id": user._meta.pk.value_to_string(user), "email": email, "code": code, } ) request.session[EMAIL_VERIFICATION_CODE_SESSION_KEY] = pending_verification return code def get_pending_verification( request: HttpRequest, peek: bool = False ) -> Tuple[Optional[EmailVerificationModel], Optional[Dict[str, Any]]]: if peek: data = request.session.get(EMAIL_VERIFICATION_CODE_SESSION_KEY) else: data = request.session.pop(EMAIL_VERIFICATION_CODE_SESSION_KEY, None) if not data: clear_state(request) return None, None if time.time() - data["at"] >= app_settings.EMAIL_VERIFICATION_BY_CODE_TIMEOUT: clear_state(request) return None, None if user_id_str := data.get("user_id"): user_id = get_user_model()._meta.pk.to_python(user_id_str) # type: ignore[union-attr] user = get_user_model().objects.get(pk=user_id) email = data["email"] try: email_address = EmailAddress.objects.get_for_user(user, email) except EmailAddress.DoesNotExist: email_address = EmailAddress(user=user, email=email) verification = EmailVerificationModel(email_address, key=data["code"]) else: verification = None return verification, data def record_invalid_attempt( request: HttpRequest, pending_verification: Dict[str, Any] ) -> bool: n = pending_verification["failed_attempts"] n += 1 pending_verification["failed_attempts"] = n if n >= app_settings.EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS: clear_state(request) return False else: request.session[EMAIL_VERIFICATION_CODE_SESSION_KEY] = pending_verification return True django-allauth-65.0.2/allauth/account/internal/flows/login.py000066400000000000000000000071551467545753200242460ustar00rootroot00000000000000import time from typing import Any, Dict from django.http import HttpRequest, HttpResponse from allauth import app_settings as allauth_settings from allauth.account.adapter import get_adapter from allauth.account.models import Login from allauth.core.exceptions import ImmediateHttpResponse AUTHENTICATION_METHODS_SESSION_KEY = "account_authentication_methods" def record_authentication(request, method, **extra_data): """Here we keep a log of all authentication methods used within the current session. Important to note is that having entries here does not imply that a user is fully signed in. For example, consider a case where a user authenticates using a password, but fails to complete the 2FA challenge. Or, a user successfully signs in into an inactive account or one that still needs verification. In such cases, ``request.user`` is still anonymous, yet, we do have an entry here. Example data:: {'method': 'password', 'at': 1701423602.7184925, 'username': 'john.doe'} {'method': 'socialaccount', 'at': 1701423567.6368647, 'provider': 'amazon', 'uid': 'amzn1.account.K2LI23KL2LK2'} {'method': 'mfa', 'at': 1701423602.6392953, 'id': 1, 'type': 'totp'} """ methods = request.session.get(AUTHENTICATION_METHODS_SESSION_KEY, []) data = { "method": method, "at": time.time(), **extra_data, } methods.append(data) request.session[AUTHENTICATION_METHODS_SESSION_KEY] = methods def _get_login_hook_kwargs(login: Login) -> Dict[str, Any]: """ TODO: Just break backwards compatibility and pass only `login` to `pre/post_login()`. """ return dict( email_verification=login.email_verification, redirect_url=login.redirect_url, signal_kwargs=login.signal_kwargs, signup=login.signup, email=login.email, ) def perform_password_login( request: HttpRequest, credentials: Dict[str, Any], login: Login ) -> HttpResponse: extra_data = { field: credentials.get(field) for field in ["email", "username"] if credentials.get(field) } record_authentication(request, method="password", **extra_data) return perform_login(request, login) def perform_login(request: HttpRequest, login: Login) -> HttpResponse: adapter = get_adapter() hook_kwargs = _get_login_hook_kwargs(login) response = adapter.pre_login(request, login.user, **hook_kwargs) if response: return response return resume_login(request, login) def resume_login(request: HttpRequest, login: Login) -> HttpResponse: from allauth.account.stages import LoginStageController adapter = get_adapter() ctrl = LoginStageController(request, login) try: response = ctrl.handle() if response: return response adapter.login(request, login.user) hook_kwargs = _get_login_hook_kwargs(login) response = adapter.post_login(request, login.user, **hook_kwargs) if response: return response except ImmediateHttpResponse as e: if allauth_settings.HEADLESS_ENABLED: from allauth.headless.internal.restkit.response import APIResponse if isinstance(e.response, APIResponse): raise e response = e.response return response def is_login_rate_limited(request, login: Login) -> bool: from allauth.account.internal.flows.email_verification import ( is_verification_rate_limited, ) if is_verification_rate_limited(request, login): return True return False django-allauth-65.0.2/allauth/account/internal/flows/login_by_code.py000066400000000000000000000103001467545753200257140ustar00rootroot00000000000000import time from typing import Any, Dict, Optional, Tuple from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.auth.models import AbstractBaseUser from django.http import HttpRequest from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.internal.flows.email_verification import ( verify_email_indirectly, ) from allauth.account.internal.flows.login import ( perform_login, record_authentication, ) from allauth.account.internal.flows.signup import send_unknown_account_mail from allauth.account.internal.stagekit import clear_login, stash_login from allauth.account.models import Login LOGIN_CODE_STATE_KEY = "login_code" def request_login_code( request: HttpRequest, email: str, login: Optional[Login] = None ) -> None: from allauth.account.utils import filter_users_by_email initiated_by_user = login is None adapter = get_adapter() users = filter_users_by_email(email, is_active=True, prefer_verified=True) pending_login = { "at": time.time(), "email": email, "failed_attempts": 0, "initiated_by_user": initiated_by_user, } if not users: user = None send_unknown_account_mail(request, email) else: user = users[0] code = adapter.generate_login_code() context = { "request": request, "code": code, } adapter.send_mail("account/email/login_code", email, context) pending_login.update( {"code": code, "user_id": user._meta.pk.value_to_string(user)} ) adapter.add_message( request, messages.SUCCESS, "account/messages/login_code_sent.txt", {"email": email}, ) if initiated_by_user: login = Login(user=user, email=email) login.state["stages"] = {"current": "login_by_code"} assert login login.state[LOGIN_CODE_STATE_KEY] = pending_login if initiated_by_user: stash_login(request, login) def get_pending_login( request, login: Login, peek: bool = False ) -> Tuple[Optional[AbstractBaseUser], Optional[Dict[str, Any]]]: if peek: data = login.state.get(LOGIN_CODE_STATE_KEY) else: data = login.state.pop(LOGIN_CODE_STATE_KEY, None) if not data: return None, None if time.time() - data["at"] >= app_settings.LOGIN_BY_CODE_TIMEOUT: login.state.pop(LOGIN_CODE_STATE_KEY, None) clear_login(request) return None, None user_id_str = data.get("user_id") user = None if user_id_str: user_id = get_user_model()._meta.pk.to_python(user_id_str) # type: ignore[union-attr] user = get_user_model().objects.get(pk=user_id) return user, data def record_invalid_attempt(request, login: Login) -> bool: from allauth.account.internal.stagekit import stash_login, unstash_login pending_login = login.state[LOGIN_CODE_STATE_KEY] n = pending_login["failed_attempts"] n += 1 pending_login["failed_attempts"] = n if n >= app_settings.LOGIN_BY_CODE_MAX_ATTEMPTS: unstash_login(request) return False else: login.state[LOGIN_CODE_STATE_KEY] = pending_login stash_login(request, login) return True def perform_login_by_code( request: HttpRequest, stage, redirect_url: Optional[str], ): state = stage.login.state[LOGIN_CODE_STATE_KEY] email = state["email"] user = stage.login.user record_authentication(request, method="code", email=email) verify_email_indirectly(request, user, email) if state["initiated_by_user"]: # Just requesting a login code does is not considered to be a real login, # yet, is needed in order to make the stage machinery work. Now that we've # completed the code, let's start a real login. login = Login( user=user, redirect_url=redirect_url, email=email, ) return perform_login(request, login) else: return stage.exit() def compare_code(*, actual, expected) -> bool: actual = actual.replace(" ", "").lower() expected = expected.replace(" ", "").lower() return expected and actual == expected django-allauth-65.0.2/allauth/account/internal/flows/logout.py000066400000000000000000000007231467545753200244410ustar00rootroot00000000000000from django.contrib import messages from django.http import HttpRequest from allauth.account.internal.stagekit import clear_login def logout(request: HttpRequest) -> None: from allauth.account.adapter import get_adapter if request.user.is_authenticated: adapter = get_adapter() adapter.add_message( request, messages.SUCCESS, "account/messages/logged_out.txt" ) adapter.logout(request) clear_login(request) django-allauth-65.0.2/allauth/account/internal/flows/manage_email.py000066400000000000000000000131131467545753200255240ustar00rootroot00000000000000from typing import Optional from django.contrib import messages from django.http import HttpRequest from allauth.account import app_settings, signals from allauth.account.adapter import get_adapter from allauth.account.internal.flows.reauthentication import ( raise_if_reauthentication_required, ) from allauth.account.models import EmailAddress def can_delete_email(email_address: EmailAddress) -> bool: adapter = get_adapter() return adapter.can_delete_email(email_address) def delete_email(request: HttpRequest, email_address: EmailAddress) -> bool: if app_settings.REAUTHENTICATION_REQUIRED: raise_if_reauthentication_required(request) success = False adapter = get_adapter() if not can_delete_email(email_address): adapter.add_message( request, messages.ERROR, "account/messages/cannot_delete_primary_email.txt", {"email": email_address.email}, ) else: email_address.remove() signals.email_removed.send( sender=EmailAddress, request=request, user=request.user, email_address=email_address, ) adapter.add_message( request, messages.SUCCESS, "account/messages/email_deleted.txt", {"email": email_address.email}, ) adapter.send_notification_mail( "account/email/email_deleted", request.user, {"deleted_email": email_address.email}, ) success = True return success def add_email(request: HttpRequest, form): if app_settings.REAUTHENTICATION_REQUIRED: raise_if_reauthentication_required(request) email_address = form.save(request) adapter = get_adapter(request) adapter.add_message( request, messages.INFO, "account/messages/email_confirmation_sent.txt", {"email": form.cleaned_data["email"]}, ) if email_address.pk: signals.email_added.send( sender=EmailAddress, request=request, user=request.user, email_address=email_address, ) def can_mark_as_primary(email_address: EmailAddress): return ( email_address.verified or not EmailAddress.objects.filter( user=email_address.user, verified=True ).exists() ) def mark_as_primary(request: HttpRequest, email_address: EmailAddress): if app_settings.REAUTHENTICATION_REQUIRED: raise_if_reauthentication_required(request) # Not primary=True -- Slightly different variation, don't # require verified unless moving from a verified # address. Ignore constraint if previous primary email # address is not verified. success = False if not can_mark_as_primary(email_address): get_adapter().add_message( request, messages.ERROR, "account/messages/unverified_primary_email.txt", ) else: assert request.user.is_authenticated from_email_address = EmailAddress.objects.filter( user=request.user, primary=True ).first() email_address.set_as_primary() adapter = get_adapter() adapter.add_message( request, messages.SUCCESS, "account/messages/primary_email_set.txt", ) emit_email_changed(request, from_email_address, email_address) success = True return success def emit_email_changed(request, from_email_address, to_email_address) -> None: user = to_email_address.user signals.email_changed.send( sender=EmailAddress, request=request, user=user, from_email_address=from_email_address, to_email_address=to_email_address, ) if from_email_address: get_adapter().send_notification_mail( "account/email/email_changed", user, context={ "from_email": from_email_address.email, "to_email": to_email_address.email, }, email=from_email_address.email, ) def assess_unique_email(email) -> Optional[bool]: """ True -- email is unique False -- email is already in use None -- email is in use, but we should hide that using email verification. """ from allauth.account.utils import filter_users_by_email if not filter_users_by_email(email): # All good. return True elif not app_settings.PREVENT_ENUMERATION: # Fail right away. return False elif ( app_settings.EMAIL_VERIFICATION == app_settings.EmailVerificationMethod.MANDATORY ): # In case of mandatory verification and enumeration prevention, # we can avoid creating a new account with the same (unverified) # email address, because we are going to send an email anyway. assert app_settings.PREVENT_ENUMERATION return None elif app_settings.PREVENT_ENUMERATION == "strict": # We're going to be strict on enumeration prevention, and allow for # this email address to pass even though it already exists. In this # scenario, you can signup multiple times using the same email # address resulting in multiple accounts with an unverified email. return True else: assert app_settings.PREVENT_ENUMERATION is True # Conflict. We're supposed to prevent enumeration, but we can't # because that means letting the user in, while emails are required # to be unique. In this case, uniqueness takes precedence over # enumeration prevention. return False django-allauth-65.0.2/allauth/account/internal/flows/password_change.py000066400000000000000000000035771467545753200263110ustar00rootroot00000000000000from django.contrib import messages from django.contrib.auth import update_session_auth_hash from django.contrib.auth.models import AbstractBaseUser from django.http import HttpRequest from allauth.account import app_settings, signals from allauth.account.adapter import get_adapter from allauth.account.internal.flows.logout import logout def change_password(user: AbstractBaseUser, password: str) -> None: get_adapter().set_password(user, password) def finalize_password_change(request: HttpRequest, user: AbstractBaseUser) -> bool: logged_out = logout_on_password_change(request, user) adapter = get_adapter(request) adapter.add_message( request, messages.SUCCESS, "account/messages/password_changed.txt", ) adapter.send_notification_mail("account/email/password_changed", user) signals.password_changed.send( sender=user.__class__, request=request, user=user, ) return logged_out def finalize_password_set(request: HttpRequest, user: AbstractBaseUser) -> bool: logged_out = logout_on_password_change(request, user) adapter = get_adapter(request) adapter.add_message(request, messages.SUCCESS, "account/messages/password_set.txt") adapter.send_notification_mail("account/email/password_set", user) signals.password_set.send( sender=user.__class__, request=request, user=user, ) return logged_out def logout_on_password_change(request: HttpRequest, user: AbstractBaseUser) -> bool: # Since it is the default behavior of Django to invalidate all sessions on # password change, this function actually has to preserve the session when # logout isn't desired. logged_out = True if not app_settings.LOGOUT_ON_PASSWORD_CHANGE: update_session_auth_hash(request, user) logged_out = False else: logout(request) return logged_out django-allauth-65.0.2/allauth/account/internal/flows/password_reset.py000066400000000000000000000042661467545753200262020ustar00rootroot00000000000000from urllib.parse import quote from django.contrib import messages from django.contrib.auth.models import AbstractBaseUser from django.http import HttpRequest from django.urls import reverse from allauth.account import signals from allauth.account.adapter import get_adapter from allauth.account.models import EmailAddress from allauth.core.internal.httpkit import get_frontend_url from allauth.utils import build_absolute_uri def reset_password(user: AbstractBaseUser, password: str) -> None: get_adapter().set_password(user, password) def finalize_password_reset(request: HttpRequest, user: AbstractBaseUser) -> None: adapter = get_adapter() if user: # User successfully reset the password, clear any # possible cache entries for all email addresses. for email in EmailAddress.objects.filter(user_id=user.pk): adapter._delete_login_attempts_cached_email(request, email=email.email) adapter.add_message( request, messages.SUCCESS, "account/messages/password_changed.txt", ) signals.password_reset.send( sender=user.__class__, request=request, user=user, ) adapter.send_notification_mail("account/email/password_reset", user) def get_reset_password_url(request: HttpRequest) -> str: url = get_frontend_url(request, "account_reset_password") if not url: url = build_absolute_uri(request, reverse("account_reset_password")) return url def get_reset_password_from_key_url(request: HttpRequest, key: str) -> str: """ Method intented to be overriden in case the password reset email needs to point to your frontend/SPA. """ url = get_frontend_url(request, "account_reset_password_from_key", key=key) if not url: # We intentionally accept an opaque `key` on the interface here, and not # implementation details such as a separate `uidb36` and `key. Ideally, # this should have done on `urls` level as well. path = reverse( "account_reset_password_from_key", kwargs={"uidb36": "UID", "key": "KEY"} ) path = path.replace("UID-KEY", quote(key)) url = build_absolute_uri(request, path) return url django-allauth-65.0.2/allauth/account/internal/flows/reauthentication.py000066400000000000000000000075431467545753200265050ustar00rootroot00000000000000import time from typing import Dict, List, Optional from django.contrib.auth import REDIRECT_FIELD_NAME from django.http import HttpRequest, HttpResponseRedirect from django.urls import resolve, reverse from django.utils.http import urlencode from allauth import app_settings as allauth_settings from allauth.account import app_settings from allauth.account.authentication import get_authentication_records from allauth.account.internal.flows.login import record_authentication from allauth.core.exceptions import ReauthenticationRequired from allauth.core.internal.httpkit import ( deserialize_request, serialize_request, ) from allauth.utils import import_callable STATE_SESSION_KEY = "account_reauthentication_state" def reauthenticate_by_password(request: HttpRequest) -> None: record_authentication(request, method="password", reauthenticated=True) def stash_and_reauthenticate( request: HttpRequest, state: dict, callback: str ) -> HttpResponseRedirect: request.session[STATE_SESSION_KEY] = { "state": state, "callback": callback, } return HttpResponseRedirect(reverse("account_reauthenticate")) def suspend_request(request: HttpRequest, redirect_to: str) -> HttpResponseRedirect: path = request.get_full_path() if request.method == "POST": request.session[STATE_SESSION_KEY] = {"request": serialize_request(request)} return HttpResponseRedirect( redirect_to + "?" + urlencode({REDIRECT_FIELD_NAME: path}) ) def resume_request(request: HttpRequest) -> Optional[HttpResponseRedirect]: from allauth.account.utils import get_next_redirect_url state = request.session.pop(STATE_SESSION_KEY, None) if state and "callback" in state: callback = import_callable(state["callback"]) return callback(request, state["state"]) url = get_next_redirect_url(request, REDIRECT_FIELD_NAME) if not url: return None if state and "request" in state: suspended_request = deserialize_request(state["request"], request) if suspended_request.path == url: resolved = resolve(suspended_request.path) return resolved.func(suspended_request, *resolved.args, **resolved.kwargs) return HttpResponseRedirect(url) def raise_if_reauthentication_required(request: HttpRequest) -> None: if not did_recently_authenticate(request): raise ReauthenticationRequired() def did_recently_authenticate(request: HttpRequest) -> bool: if request.user.is_anonymous: return False if not get_reauthentication_flows(request.user): # TODO: This user only has social accounts attached. Now, ideally, you # would want to reauthenticate over at the social account provider. For # now, this is not implemented. Although definitely suboptimal, this # method is currently used for reauthentication checks over at MFA, and, # users that delegate the security of their account to an external # provider like Google typically use MFA over there anyway. return True methods = get_authentication_records(request) if not methods: return False authenticated_at = methods[-1]["at"] return time.time() - authenticated_at < app_settings.REAUTHENTICATION_TIMEOUT def get_reauthentication_flows(user) -> List[Dict]: ret: List[Dict] = [] if not user.is_authenticated: return ret if user.has_usable_password(): entry = { "id": "reauthenticate", } ret.append(entry) if allauth_settings.MFA_ENABLED: from allauth.mfa.models import Authenticator from allauth.mfa.utils import is_mfa_enabled types = [] for typ in Authenticator.Type: if is_mfa_enabled(user, types=[typ]): types.append(typ) if types: ret.append({"id": "mfa_reauthenticate", "types": types}) return ret django-allauth-65.0.2/allauth/account/internal/flows/signup.py000066400000000000000000000043341467545753200244370ustar00rootroot00000000000000from django.contrib import messages from django.http import HttpRequest, HttpResponse from django.urls import reverse from allauth.account import app_settings, signals from allauth.account.adapter import get_adapter from allauth.account.internal.flows import email_verification_by_code from allauth.account.internal.flows.login import perform_login from allauth.account.models import Login from allauth.core.internal.httpkit import get_frontend_url from allauth.utils import build_absolute_uri def prevent_enumeration(request: HttpRequest, email: str) -> HttpResponse: adapter = get_adapter(request) adapter.send_account_already_exists_mail(email) adapter.add_message( request, messages.INFO, "account/messages/email_confirmation_sent.txt", {"email": email, "login": False, "signup": True}, ) if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: email_verification_by_code.request_email_verification_code( request, user=None, email=email ) resp = adapter.respond_email_verification_sent(request, None) return resp def send_unknown_account_mail(request: HttpRequest, email: str) -> None: if not app_settings.EMAIL_UNKNOWN_ACCOUNTS: return None signup_url = get_signup_url(request) context = { "request": request, "signup_url": signup_url, } get_adapter().send_mail("account/email/unknown_account", email, context) def get_signup_url(request: HttpRequest) -> str: url = get_frontend_url(request, "account_signup") if not url: url = build_absolute_uri(request, reverse("account_signup")) return url def complete_signup( request, *, user, email_verification=None, redirect_url=None, signal_kwargs=None, by_passkey=False, ): if signal_kwargs is None: signal_kwargs = {} signals.user_signed_up.send( sender=user.__class__, request=request, user=user, **signal_kwargs ) login = Login( user=user, email_verification=email_verification, redirect_url=redirect_url, signal_kwargs=signal_kwargs, signup=True, ) if by_passkey: login.state["passkey_signup"] = True return perform_login(request, login) django-allauth-65.0.2/allauth/account/internal/stagekit.py000066400000000000000000000031321467545753200236060ustar00rootroot00000000000000import time from typing import Optional from django.http import HttpResponseRedirect from django.urls import reverse from allauth.account import app_settings from allauth.account.models import Login from allauth.account.stages import LoginStage, LoginStageController LOGIN_SESSION_KEY = "account_login" def get_pending_stage(request) -> Optional[LoginStage]: stage = None if not request.user.is_authenticated: login = unstash_login(request, peek=True) if login: ctrl = LoginStageController(request, login) stage = ctrl.get_pending_stage() return stage def redirect_to_pending_stage(request, stage: LoginStage): if stage.urlname: return HttpResponseRedirect(reverse(stage.urlname)) clear_login(request) return HttpResponseRedirect(reverse("account_login")) def clear_login(request): request.session.pop(LOGIN_SESSION_KEY, None) def unstash_login(request, peek=False): login = None if peek: data = request.session.get(LOGIN_SESSION_KEY) else: data = request.session.pop(LOGIN_SESSION_KEY, None) if isinstance(data, dict): try: login = Login.deserialize(data) except ValueError: pass else: if time.time() - login.initiated_at > app_settings.LOGIN_TIMEOUT: login = None clear_login(request) else: request._account_login_accessed = True return login def stash_login(request, login): request.session[LOGIN_SESSION_KEY] = login.serialize() request._account_login_accessed = True django-allauth-65.0.2/allauth/account/management/000077500000000000000000000000001467545753200217225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/management/__init__.py000066400000000000000000000000001467545753200240210ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/management/commands/000077500000000000000000000000001467545753200235235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/management/commands/__init__.py000066400000000000000000000000001467545753200256220ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/management/commands/account_unsetmultipleprimaryemails.py000066400000000000000000000032261467545753200333250ustar00rootroot00000000000000from django.contrib.auth import get_user_model from django.core.management.base import BaseCommand from django.db.models import Count from allauth.account.models import EmailAddress from allauth.account.utils import user_email class Command(BaseCommand): def handle(self, *args, **options): for user in self.get_users_with_multiple_primary_email(): self.unprimary_extra_primary_emails(user) def get_users_with_multiple_primary_email(self): user_pks = [] for email_address_dict in ( EmailAddress.objects.filter(primary=True) .values("user") .annotate(Count("user")) .filter(user__count__gt=1) ): user_pks.append(email_address_dict["user"]) return get_user_model().objects.filter(pk__in=user_pks) def unprimary_extra_primary_emails(self, user): primary_email_addresses = EmailAddress.objects.filter(user=user, primary=True) for primary_email_address in primary_email_addresses: if primary_email_address.email == user_email(user): break else: # Didn't find the main email addresses and break the for loop print( "WARNING: Multiple primary without a user.email match for" "user pk %s; (tried: %s, using: %s)" ) % ( user.pk, ", ".join( [email_address.email for email_address in primary_email_addresses] ), primary_email_address, ) primary_email_addresses.exclude(pk=primary_email_address.pk).update( primary=False ) django-allauth-65.0.2/allauth/account/managers.py000066400000000000000000000110651467545753200217600ustar00rootroot00000000000000from datetime import timedelta from typing import Optional from django.db import models from django.db.models import Q from django.utils import timezone from . import app_settings class EmailAddressManager(models.Manager): def can_add_email(self, user): ret = True if app_settings.CHANGE_EMAIL: # We always allow adding an email in this case, regardless of # `MAX_EMAIL_ADDRESSES`, as adding actually adds a temporary email # that the user wants to change to. return True elif app_settings.MAX_EMAIL_ADDRESSES: count = self.filter(user=user).count() ret = count < app_settings.MAX_EMAIL_ADDRESSES return ret def get_new(self, user): """ Returns the email address the user is in the process of changing to, if any. """ assert app_settings.CHANGE_EMAIL return ( self.model.objects.filter(user=user, verified=False).order_by("pk").last() ) def add_new_email(self, request, user, email): """ Adds an email address the user wishes to change to, replacing his current email address once confirmed. """ assert app_settings.CHANGE_EMAIL instance = self.get_new(user) email = email.lower() if not instance: instance = self.model.objects.create(user=user, email=email) else: # Apparently, the user was already in the process of changing his # email. Reuse that temporary email address. instance.email = email instance.verified = False instance.primary = False instance.save() instance.send_confirmation(request) return instance def add_email(self, request, user, email, confirm=False, signup=False): email = email.lower() email_address, created = self.get_or_create( user=user, email=email, defaults={"email": email} ) if created and confirm: email_address.send_confirmation(request, signup=signup) return email_address def get_verified(self, user): return self.filter(user=user, verified=True).order_by("-primary", "pk").first() def get_primary(self, user): try: return self.get(user=user, primary=True) except self.model.DoesNotExist: return None def get_primary_email(self, user) -> Optional[str]: from allauth.account.utils import user_email primary = self.get_primary(user) if primary: email = primary.email else: email = user_email(user) return email def get_users_for(self, email): # this is a list rather than a generator because we probably want to # do a len() on it right away return [ address.user for address in self.filter(verified=True, email=email.lower()) ] def fill_cache_for_user(self, user, addresses): """ In a multi-db setup, inserting records and re-reading them later on may result in not being able to find newly inserted records. Therefore, we maintain a cache for the user so that we can avoid database access when we need to re-read.. """ user._emailaddress_cache = addresses def get_for_user(self, user, email): cache_key = "_emailaddress_cache" addresses = getattr(user, cache_key, None) email = email.lower() if addresses is None: ret = self.get(user=user, email=email) # To avoid additional lookups when e.g. # EmailAddress.set_as_primary() starts touching self.user ret.user = user return ret else: for address in addresses: if address.email == email: return address raise self.model.DoesNotExist() def is_verified(self, email): return self.filter(email=email.lower(), verified=True).exists() def lookup(self, emails): return self.filter(email__in=[e.lower() for e in emails]) class EmailConfirmationManager(models.Manager): def all_expired(self): return self.filter(self.expired_q()) def all_valid(self): return self.exclude(self.expired_q()).filter(email_address__verified=False) def expired_q(self): sent_threshold = timezone.now() - timedelta( days=app_settings.EMAIL_CONFIRMATION_EXPIRE_DAYS ) return Q(sent__lt=sent_threshold) def delete_expired_confirmations(self): self.all_expired().delete() django-allauth-65.0.2/allauth/account/middleware.py000066400000000000000000000064421467545753200223030ustar00rootroot00000000000000import os from types import SimpleNamespace from django.http import HttpResponseRedirect from django.urls import NoReverseMatch, reverse from django.utils.decorators import sync_and_async_middleware from asgiref.sync import iscoroutinefunction from allauth.account.adapter import get_adapter from allauth.account.internal import flows from allauth.core import context from allauth.core.exceptions import ( ImmediateHttpResponse, ReauthenticationRequired, ) @sync_and_async_middleware def AccountMiddleware(get_response): if iscoroutinefunction(get_response): async def middleware(request): request.allauth = SimpleNamespace() with context.request_context(request): response = await get_response(request) if _should_redirect_accounts(request, response): response = await _aredirect_accounts(request) return response else: def middleware(request): request.allauth = SimpleNamespace() with context.request_context(request): response = get_response(request) if _should_redirect_accounts(request, response): response = _redirect_accounts(request) return response def process_exception(request, exception): if isinstance(exception, ImmediateHttpResponse): return exception.response elif isinstance(exception, ReauthenticationRequired): redirect_url = reverse("account_login") methods = get_adapter().get_reauthentication_methods(request.user) if methods: redirect_url = methods[0]["url"] return flows.reauthentication.suspend_request(request, redirect_url) middleware.process_exception = process_exception return middleware def _should_redirect_accounts(request, response) -> bool: """ URLs should be hackable. Yet, assuming allauth is included like this... path("accounts/", include("allauth.urls")), ... and a user would attempt to navigate to /accounts/, a 404 would be presented. This code catches that 404, and redirects to either the email management overview or the login page, depending on whether or not the user is authenticated. """ if response.status_code != 404: return False try: login_path = reverse("account_login") email_path = reverse("account_email") except NoReverseMatch: # Project might have deviated URLs, let's keep out of the way. return False prefix = os.path.commonprefix([login_path, email_path]) if len(prefix) <= 1 or prefix != request.path: return False # If we have a prefix that is not just '/', and that is what our request is # pointing to, redirect. return True async def _aredirect_accounts(request) -> HttpResponseRedirect: email_path = reverse("account_email") login_path = reverse("account_login") user = await request.auser() return HttpResponseRedirect(email_path if user.is_authenticated else login_path) def _redirect_accounts(request) -> HttpResponseRedirect: email_path = reverse("account_email") login_path = reverse("account_login") user = request.user return HttpResponseRedirect(email_path if user.is_authenticated else login_path) django-allauth-65.0.2/allauth/account/migrations/000077500000000000000000000000001467545753200217625ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/migrations/0001_initial.py000066400000000000000000000063751467545753200244400ustar00rootroot00000000000000import django.utils.timezone from django.conf import settings from django.db import migrations, models UNIQUE_EMAIL = getattr(settings, "ACCOUNT_UNIQUE_EMAIL", True) class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name="EmailAddress", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ( "email", models.EmailField( unique=UNIQUE_EMAIL, max_length=75, verbose_name="email address", ), ), ( "verified", models.BooleanField(default=False, verbose_name="verified"), ), ( "primary", models.BooleanField(default=False, verbose_name="primary"), ), ( "user", models.ForeignKey( verbose_name="user", to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, ), ), ], options={ "verbose_name": "email address", "verbose_name_plural": "email addresses", }, bases=(models.Model,), ), migrations.CreateModel( name="EmailConfirmation", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ( "created", models.DateTimeField( default=django.utils.timezone.now, verbose_name="created", ), ), ("sent", models.DateTimeField(null=True, verbose_name="sent")), ( "key", models.CharField(unique=True, max_length=64, verbose_name="key"), ), ( "email_address", models.ForeignKey( verbose_name="email address", to="account.EmailAddress", on_delete=models.CASCADE, ), ), ], options={ "verbose_name": "email confirmation", "verbose_name_plural": "email confirmations", }, bases=(models.Model,), ), ] if not UNIQUE_EMAIL: operations += [ migrations.AlterUniqueTogether( name="emailaddress", unique_together=set([("user", "email")]), ), ] django-allauth-65.0.2/allauth/account/migrations/0002_email_max_length.py000066400000000000000000000015111467545753200262700ustar00rootroot00000000000000from django.conf import settings from django.db import migrations, models UNIQUE_EMAIL = getattr(settings, "ACCOUNT_UNIQUE_EMAIL", True) EMAIL_MAX_LENGTH = getattr(settings, "ACCOUNT_EMAIL_MAX_LENGTH", 254) class Migration(migrations.Migration): dependencies = [ ("account", "0001_initial"), ] operations = [ migrations.AlterField( model_name="emailaddress", name="email", field=models.EmailField( unique=UNIQUE_EMAIL, max_length=EMAIL_MAX_LENGTH, verbose_name="email address", ), ), ] if not UNIQUE_EMAIL: operations += [ migrations.AlterUniqueTogether( name="emailaddress", unique_together=set([("user", "email")]), ), ] 0003_alter_emailaddress_create_unique_verified_email.py000066400000000000000000000015711467545753200345040ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/migrations# Generated by Django 4.2.2 on 2023-06-14 12:52 from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("account", "0002_email_max_length"), ] operations = ( [ migrations.AlterUniqueTogether( name="emailaddress", unique_together={("user", "email")}, ), migrations.AddConstraint( model_name="emailaddress", constraint=models.UniqueConstraint( condition=models.Q(("verified", True)), fields=["email"], name="unique_verified_email", ), ), ] if getattr(settings, "ACCOUNT_UNIQUE_EMAIL", True) else [] ) django-allauth-65.0.2/allauth/account/migrations/0004_alter_emailaddress_drop_unique_email.py000066400000000000000000000010461467545753200324050ustar00rootroot00000000000000from django.conf import settings from django.db import migrations, models EMAIL_MAX_LENGTH = getattr(settings, "ACCOUNT_EMAIL_MAX_LENGTH", 254) class Migration(migrations.Migration): dependencies = [ ("account", "0003_alter_emailaddress_create_unique_verified_email"), ] operations = [ migrations.AlterField( model_name="emailaddress", name="email", field=models.EmailField( max_length=EMAIL_MAX_LENGTH, verbose_name="email address" ), ), ] django-allauth-65.0.2/allauth/account/migrations/0005_emailaddress_idx_upper_email.py000066400000000000000000000010221467545753200306560ustar00rootroot00000000000000# Generated by Django 4.2.4 on 2023-08-23 18:17 import django.db.models.functions.text from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("account", "0004_alter_emailaddress_drop_unique_email"), ] operations = [ migrations.AddIndex( model_name="emailaddress", index=models.Index( django.db.models.functions.text.Upper("email"), name="account_emailaddress_upper", ), ), ] django-allauth-65.0.2/allauth/account/migrations/0006_emailaddress_lower.py000066400000000000000000000014311467545753200266450ustar00rootroot00000000000000from django.conf import settings from django.db import migrations from django.db.models.functions import Lower from allauth.account import app_settings def forwards(apps, schema_editor): EmailAddress = apps.get_model("account.EmailAddress") User = apps.get_model(settings.AUTH_USER_MODEL) EmailAddress.objects.all().exclude(email=Lower("email")).update( email=Lower("email") ) email_field = app_settings.USER_MODEL_EMAIL_FIELD if email_field: User.objects.all().exclude(**{email_field: Lower(email_field)}).update( **{email_field: Lower(email_field)} ) class Migration(migrations.Migration): dependencies = [ ("account", "0005_emailaddress_idx_upper_email"), ] operations = [migrations.RunPython(forwards)] django-allauth-65.0.2/allauth/account/migrations/0007_emailaddress_idx_email.py000066400000000000000000000012311467545753200274470ustar00rootroot00000000000000from django.conf import settings from django.db import migrations, models EMAIL_MAX_LENGTH = getattr(settings, "ACCOUNT_EMAIL_MAX_LENGTH", 254) class Migration(migrations.Migration): dependencies = [ ("account", "0006_emailaddress_lower"), ] operations = [ migrations.RemoveIndex( model_name="emailaddress", name="account_emailaddress_upper", ), migrations.AlterField( model_name="emailaddress", name="email", field=models.EmailField( db_index=True, max_length=EMAIL_MAX_LENGTH, verbose_name="email address" ), ), ] django-allauth-65.0.2/allauth/account/migrations/0008_emailaddress_unique_primary_email_fixup.py000066400000000000000000000030621467545753200331540ustar00rootroot00000000000000from django.conf import settings from django.db import migrations from django.db.models import Count def forwards(apps, schema_editor): EmailAddress = apps.get_model("account.EmailAddress") User = apps.get_model(settings.AUTH_USER_MODEL) user_email_field = getattr(settings, "ACCOUNT_USER_MODEL_EMAIL_FIELD", "email") def get_users_with_multiple_primary_email(): user_pks = [] for email_address_dict in ( EmailAddress.objects.filter(primary=True) .values("user") .annotate(Count("user")) .filter(user__count__gt=1) ): user_pks.append(email_address_dict["user"]) return User.objects.filter(pk__in=user_pks) def unset_extra_primary_emails(user): qs = EmailAddress.objects.filter(user=user, primary=True) primary_email_addresses = list(qs) if not primary_email_addresses: return primary_email_address = primary_email_addresses[0] if user_email_field: for address in primary_email_addresses: if address.email.lower() == getattr(user, user_email_field, "").lower(): primary_email_address = address break qs.exclude(pk=primary_email_address.pk).update(primary=False) for user in get_users_with_multiple_primary_email().iterator(): unset_extra_primary_emails(user) class Migration(migrations.Migration): dependencies = [ ("account", "0007_emailaddress_idx_email"), ] operations = [migrations.RunPython(forwards)] django-allauth-65.0.2/allauth/account/migrations/0009_emailaddress_unique_primary_email.py000066400000000000000000000010411467545753200317350ustar00rootroot00000000000000# Generated by Django 4.2.11 on 2024-05-09 06:09 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("account", "0008_emailaddress_unique_primary_email_fixup"), ] operations = [ migrations.AddConstraint( model_name="emailaddress", constraint=models.UniqueConstraint( condition=models.Q(("primary", True)), fields=("user", "primary"), name="unique_primary_email", ), ), ] django-allauth-65.0.2/allauth/account/migrations/__init__.py000066400000000000000000000000001467545753200240610ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/mixins.py000066400000000000000000000146711467545753200215000ustar00rootroot00000000000000from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import ImproperlyConfigured from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect from django.utils.decorators import method_decorator from django.utils.html import format_html from django.views.decorators.cache import never_cache from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.internal import flows from allauth.account.internal.decorators import login_not_required from allauth.account.internal.stagekit import ( get_pending_stage, redirect_to_pending_stage, ) from allauth.account.utils import ( get_login_redirect_url, get_next_redirect_url, passthrough_next_redirect_url, ) from allauth.core.exceptions import ImmediateHttpResponse from allauth.utils import get_request_param def _ajax_response(request, response, form=None, data=None): adapter = get_adapter() if adapter.is_ajax(request): if isinstance(response, HttpResponseRedirect) or isinstance( response, HttpResponsePermanentRedirect ): redirect_to = response["Location"] else: redirect_to = None response = adapter.ajax_response( request, response, form=form, data=data, redirect_to=redirect_to ) return response class RedirectAuthenticatedUserMixin: @method_decorator(login_not_required) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): if app_settings.AUTHENTICATED_LOGIN_REDIRECTS: if request.user.is_authenticated: redirect_to = self.get_authenticated_redirect_url() response = HttpResponseRedirect(redirect_to) return _ajax_response(request, response) else: stage = get_pending_stage(request) if stage and stage.is_resumable(request): return redirect_to_pending_stage(request, stage) response = super().dispatch(request, *args, **kwargs) return response def get_authenticated_redirect_url(self): redirect_field_name = self.redirect_field_name return get_login_redirect_url( self.request, url=self.get_success_url(), redirect_field_name=redirect_field_name, ) class LogoutFunctionalityMixin: def logout(self): flows.logout.logout(self.request) class AjaxCapableProcessFormViewMixin: def get(self, request, *args, **kwargs): response = super().get(request, *args, **kwargs) form = self.get_form() return _ajax_response( self.request, response, form=form, data=self._get_ajax_data_if() ) def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): response = self.form_valid(form) else: response = self.form_invalid(form) return _ajax_response( self.request, response, form=form, data=self._get_ajax_data_if() ) def get_form(self, form_class=None): form = getattr(self, "_cached_form", None) if form is None: form = super().get_form(form_class) self._cached_form = form return form def _get_ajax_data_if(self): return ( self.get_ajax_data() if get_adapter(self.request).is_ajax(self.request) else None ) def get_ajax_data(self): return None class CloseableSignupMixin: template_name_signup_closed = ( "account/signup_closed." + app_settings.TEMPLATE_EXTENSION ) def dispatch(self, request, *args, **kwargs): try: if not self.is_open(): return self.closed() except ImmediateHttpResponse as e: return e.response return super().dispatch(request, *args, **kwargs) def is_open(self): return get_adapter(self.request).is_open_for_signup(self.request) def closed(self): response_kwargs = { "request": self.request, "template": self.template_name_signup_closed, } return self.response_class(**response_kwargs) class NextRedirectMixin: redirect_field_name = REDIRECT_FIELD_NAME def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) redirect_field_value = get_request_param(self.request, self.redirect_field_name) ret.update( { "redirect_field_name": self.redirect_field_name, "redirect_field_value": redirect_field_value, "redirect_field": ( format_html( '', self.redirect_field_name, redirect_field_value, ) if redirect_field_value else "" ), } ) return ret def get_success_url(self): """ We're in a mixin, so we cannot rely on the fact that our super() has a get_success_url. Also, we want to check for -- in this order: 1) The `?next=/foo` 2) The `get_succes_url()` if available. 3) The `.success_url` if available. 4) A fallback default success URL: `get_default_success_url()`. """ url = self.get_next_url() if url: return url if not url: if hasattr(super(), "get_success_url"): try: url = super().get_success_url() except ImproperlyConfigured: # Django's default get_success_url() checks self.succes_url, # and throws this if that is not set. Yet, in our case, we # want to fallback to the default. pass elif hasattr(self, "success_url"): url = self.success_url if url: url = str(url) # reverse_lazy if not url: url = self.get_default_success_url() return url def get_default_success_url(self): return None def get_next_url(self): return get_next_redirect_url(self.request, self.redirect_field_name) def passthrough_next_url(self, url): return passthrough_next_redirect_url( self.request, url, self.redirect_field_name ) django-allauth-65.0.2/allauth/account/models.py000066400000000000000000000253601467545753200214510ustar00rootroot00000000000000import datetime import time from typing import Dict, Optional from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import AbstractBaseUser from django.core import signing from django.db import models from django.db.models import Q from django.db.models.constraints import UniqueConstraint from django.utils import timezone from django.utils.translation import gettext_lazy as _ from allauth.account import app_settings, signals from allauth.account.adapter import get_adapter from allauth.account.managers import ( EmailAddressManager, EmailConfirmationManager, ) class EmailAddress(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_("user"), on_delete=models.CASCADE, ) email = models.EmailField( db_index=True, max_length=app_settings.EMAIL_MAX_LENGTH, verbose_name=_("email address"), ) verified = models.BooleanField(verbose_name=_("verified"), default=False) primary = models.BooleanField(verbose_name=_("primary"), default=False) objects = EmailAddressManager() class Meta: verbose_name = _("email address") verbose_name_plural = _("email addresses") unique_together = [("user", "email")] constraints = [ UniqueConstraint( fields=["user", "primary"], name="unique_primary_email", condition=Q(primary=True), ) ] if app_settings.UNIQUE_EMAIL: constraints.append( UniqueConstraint( fields=["email"], name="unique_verified_email", condition=Q(verified=True), ) ) def __str__(self): return self.email def clean(self): super().clean() self.email = self.email.lower() def can_set_verified(self): if self.verified: return True conflict = False if app_settings.UNIQUE_EMAIL: conflict = ( EmailAddress.objects.exclude(pk=self.pk) .filter(verified=True, email=self.email) .exists() ) return not conflict def set_verified(self, commit=True): if self.verified: return True if self.can_set_verified(): self.verified = True if commit: self.save(update_fields=["verified"]) return self.verified def set_as_primary(self, conditional=False): """Marks the email address as primary. In case of `conditional`, it is only marked as primary if there is no other primary email address set. """ from allauth.account.utils import user_email old_primary = EmailAddress.objects.get_primary(self.user) if old_primary: if conditional: return False old_primary.primary = False old_primary.save() self.primary = True self.save() user_email(self.user, self.email, commit=True) return True def send_confirmation(self, request=None, signup=False): model = get_emailconfirmation_model() confirmation = model.create(self) confirmation.send(request, signup=signup) return confirmation def remove(self): from allauth.account.utils import user_email self.delete() if user_email(self.user) == self.email: alt = ( EmailAddress.objects.filter(user=self.user) .order_by("-verified") .first() ) alt_email = "" if alt: alt_email = alt.email user_email(self.user, alt_email, commit=True) class EmailConfirmationMixin: def confirm(self, request): email_address = self.email_address if not email_address.verified: confirmed = get_adapter().confirm_email(request, email_address) if confirmed: return email_address def send(self, request=None, signup=False): get_adapter().send_confirmation_mail(request, self, signup) signals.email_confirmation_sent.send( sender=self.__class__, request=request, confirmation=self, signup=signup, ) class EmailConfirmation(EmailConfirmationMixin, models.Model): email_address = models.ForeignKey( EmailAddress, verbose_name=_("email address"), on_delete=models.CASCADE, ) created = models.DateTimeField(verbose_name=_("created"), default=timezone.now) sent = models.DateTimeField(verbose_name=_("sent"), null=True) key = models.CharField(verbose_name=_("key"), max_length=64, unique=True) objects = EmailConfirmationManager() class Meta: verbose_name = _("email confirmation") verbose_name_plural = _("email confirmations") def __str__(self): return "confirmation for %s" % self.email_address @classmethod def create(cls, email_address): key = get_adapter().generate_emailconfirmation_key(email_address.email) return cls._default_manager.create(email_address=email_address, key=key) @classmethod def from_key(cls, key): qs = EmailConfirmation.objects.all_valid() qs = qs.select_related("email_address__user") emailconfirmation = qs.filter(key=key.lower()).first() return emailconfirmation def key_expired(self): expiration_date = self.sent + datetime.timedelta( days=app_settings.EMAIL_CONFIRMATION_EXPIRE_DAYS ) return expiration_date <= timezone.now() key_expired.boolean = True # type: ignore[attr-defined] def confirm(self, request): if not self.key_expired(): return super().confirm(request) def send(self, request=None, signup=False): super().send(request=request, signup=signup) self.sent = timezone.now() self.save() class EmailConfirmationHMAC(EmailConfirmationMixin): def __init__(self, email_address): self.email_address = email_address @classmethod def create(cls, email_address): return EmailConfirmationHMAC(email_address) @property def key(self): return signing.dumps(obj=self.email_address.pk, salt=app_settings.SALT) @classmethod def from_key(cls, key): try: max_age = 60 * 60 * 24 * app_settings.EMAIL_CONFIRMATION_EXPIRE_DAYS pk = signing.loads(key, max_age=max_age, salt=app_settings.SALT) ret = EmailConfirmationHMAC(EmailAddress.objects.get(pk=pk, verified=False)) except ( signing.SignatureExpired, signing.BadSignature, EmailAddress.DoesNotExist, ): ret = None return ret def key_expired(self): return False class Login: """ Represents a user that is in the process of logging in. Keyword arguments: signup -- Indicates whether or not sending the email is essential (during signup), or if it can be skipped (e.g. in case email verification is optional and we are only logging in). """ # Optional, because we might be prentending logins to prevent user # enumeration. user: Optional[AbstractBaseUser] email_verification: app_settings.EmailVerificationMethod signal_kwargs: Optional[Dict] signup: bool email: Optional[str] state: Dict initiated_at: float redirect_url: Optional[str] def __init__( self, user, email_verification: Optional[app_settings.EmailVerificationMethod] = None, redirect_url: Optional[str] = None, signal_kwargs: Optional[Dict] = None, signup: bool = False, email: Optional[str] = None, state: Optional[Dict] = None, initiated_at: Optional[float] = None, ): self.user = user if not email_verification: email_verification = app_settings.EMAIL_VERIFICATION self.email_verification = email_verification self.redirect_url = redirect_url self.signal_kwargs = signal_kwargs self.signup = signup self.email = email self.state = {} if state is None else state self.initiated_at = initiated_at if initiated_at else time.time() def serialize(self): from allauth.account.utils import user_pk_to_url_str # :-( Knowledge of the `socialaccount` is entering the `account` app. signal_kwargs = self.signal_kwargs if signal_kwargs is not None: sociallogin = signal_kwargs.get("sociallogin") if sociallogin is not None: signal_kwargs = signal_kwargs.copy() signal_kwargs["sociallogin"] = sociallogin.serialize() data = { "user_pk": user_pk_to_url_str(self.user) if self.user else None, "email_verification": self.email_verification, "signup": self.signup, "redirect_url": self.redirect_url, "email": self.email, "signal_kwargs": signal_kwargs, "state": self.state, "initiated_at": self.initiated_at, } return data @classmethod def deserialize(cls, data): from allauth.account.utils import url_str_to_user_pk user = None user_pk = data["user_pk"] if user_pk is not None: user = ( get_user_model().objects.filter(pk=url_str_to_user_pk(user_pk)).first() ) try: # :-( Knowledge of the `socialaccount` is entering the `account` app. signal_kwargs = data["signal_kwargs"] if signal_kwargs is not None: sociallogin = signal_kwargs.get("sociallogin") if sociallogin is not None: from allauth.socialaccount.models import SocialLogin signal_kwargs = signal_kwargs.copy() signal_kwargs["sociallogin"] = SocialLogin.deserialize(sociallogin) return Login( user=user, email_verification=data["email_verification"], redirect_url=data["redirect_url"], signup=data["signup"], signal_kwargs=signal_kwargs, state=data["state"], initiated_at=data["initiated_at"], ) except KeyError: raise ValueError() def get_emailconfirmation_model(): if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: from allauth.account.internal.flows.email_verification_by_code import ( EmailVerificationModel, ) return EmailVerificationModel elif app_settings.EMAIL_CONFIRMATION_HMAC: model = EmailConfirmationHMAC else: model = EmailConfirmation return model django-allauth-65.0.2/allauth/account/reauthentication.py000066400000000000000000000004641467545753200235320ustar00rootroot00000000000000import warnings from allauth.account.internal.flows.reauthentication import ( did_recently_authenticate, raise_if_reauthentication_required, ) __all__ = [ "raise_if_reauthentication_required", "did_recently_authenticate", ] warnings.warn("allauth.account.reauthentication is deprecated") django-allauth-65.0.2/allauth/account/signals.py000066400000000000000000000020121467545753200216130ustar00rootroot00000000000000from django.contrib.auth.signals import user_logged_out # noqa from django.dispatch import Signal # Provides the arguments "request", "user" user_logged_in = Signal() # Typically followed by `user_logged_in` (unless, email verification kicks in) # Provides the arguments "request", "user" user_signed_up = Signal() # Provides the arguments "request", "user" password_set = Signal() # Provides the arguments "request", "user" password_changed = Signal() # Provides the arguments "request", "user" password_reset = Signal() # Provides the arguments "request", "email_address" email_confirmed = Signal() # Provides the arguments "request", "confirmation", "signup" email_confirmation_sent = Signal() # Provides the arguments "request", "user", "from_email_address", # "to_email_address" email_changed = Signal() # Provides the arguments "request", "user", "email_address" email_added = Signal() # Provides the arguments "request", "user", "email_address" email_removed = Signal() # Internal/private signal. _add_email = Signal() django-allauth-65.0.2/allauth/account/stages.py000066400000000000000000000136001467545753200214460ustar00rootroot00000000000000from typing import Optional from django.http import HttpResponseRedirect from django.urls import reverse from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.app_settings import EmailVerificationMethod from allauth.account.models import EmailAddress from allauth.core.internal.httpkit import headed_redirect_response from allauth.utils import import_callable class LoginStage: key: str # Set in subclasses urlname: Optional[str] = None def __init__(self, controller, request, login): if not self.key: raise ValueError() self.controller = controller self.request = request self.login = login self.state = ( self.login.state.setdefault("stages", {}) .setdefault(self.key, {}) .setdefault("data", {}) ) def handle(self): return None, True def exit(self): from allauth.account.internal.flows.login import resume_login self.controller.set_handled(self.key) return resume_login(self.request, self.login) def abort(self): from allauth.account.internal.stagekit import clear_login clear_login(self.request) return HttpResponseRedirect(reverse("account_login")) def is_resumable(self, request): return True class LoginStageController: def __init__(self, request, login): self.request = request self.login = login self.state = self.login.state.setdefault("stages", {}) @classmethod def enter(cls, request, stage_key): from allauth.account.internal.stagekit import unstash_login login = unstash_login(request, peek=True) if not login: return None ctrl = LoginStageController(request, login) if ctrl.state.get("current") != stage_key: return None stages = ctrl.get_stages() for stage in stages: if stage.key == stage_key: return stage return None def set_current(self, stage_key): self.state["current"] = stage_key def is_handled(self, stage_key): return self.state.get(stage_key, {}).get("handled", False) def set_handled(self, stage_key): stage_state = self.state.setdefault(stage_key, {}) stage_state["handled"] = True def get_pending_stage(self) -> Optional[LoginStage]: ret = None stages = self.get_stages() for stage in stages: if self.is_handled(stage.key): continue ret = stage break return ret def get_stages(self): stages = [] adapter = get_adapter(self.request) paths = adapter.get_login_stages() for path in paths: cls = import_callable(path) stage = cls(self, self.request, self.login) stages.append(stage) return stages def handle(self): from allauth.account.internal.stagekit import clear_login, stash_login stages = self.get_stages() for stage in stages: if self.is_handled(stage.key): continue self.set_current(stage.key) response, cont = stage.handle() if response: if cont: stash_login(self.request, self.login) else: clear_login(self.request) return response else: assert cont self.set_handled(stage.key) clear_login(self.request) class EmailVerificationStage(LoginStage): key = "verify_email" urlname = "account_email_verification_sent" def is_resumable(self, request): return app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED def handle(self): from allauth.account.utils import ( has_verified_email, send_email_confirmation, ) response, cont = None, True login = self.login email_verification = login.email_verification if email_verification == EmailVerificationMethod.NONE: pass elif email_verification == EmailVerificationMethod.OPTIONAL: # In case of OPTIONAL verification: send on signup. if not has_verified_email(login.user, login.email) and login.signup: send_email_confirmation( self.request, login.user, signup=login.signup, email=login.email ) elif email_verification == EmailVerificationMethod.MANDATORY: if not has_verified_email(login.user, login.email): send_email_confirmation( self.request, login.user, signup=login.signup, email=login.email ) response = get_adapter().respond_email_verification_sent( self.request, login.user ) return response, cont class LoginByCodeStage(LoginStage): key = "login_by_code" urlname = "account_confirm_login_code" def handle(self): from allauth.account.internal.flows import login_by_code user, data = login_by_code.get_pending_login( self.request, self.login, peek=True ) login_by_code_required = get_adapter().is_login_by_code_required(self.login) if data is None and not login_by_code_required: # No pending login, just continue. return None, True elif data is None and login_by_code_required: email = EmailAddress.objects.get_primary_email(self.login.user) if not email: # No way of contacting the user.. cannot meet the # requirements. Abort. return headed_redirect_response("account_login"), False login_by_code.request_login_code(self.request, email, login=self.login) response = headed_redirect_response("account_confirm_login_code") return response, True django-allauth-65.0.2/allauth/account/templatetags/000077500000000000000000000000001467545753200223005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/templatetags/__init__.py000066400000000000000000000000001467545753200243770ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/templatetags/account.py000066400000000000000000000007411467545753200243100ustar00rootroot00000000000000from django import template from allauth.account.utils import user_display register = template.Library() @register.simple_tag(name="user_display") def user_display_tag(user): """ Example usage:: {% user_display user %} or if you need to use in a {% blocktrans %}:: {% user_display user as user_display %} {% blocktrans %} {{ user_display }} has sent you a gift. {% endblocktrans %} """ return user_display(user) django-allauth-65.0.2/allauth/account/tests/000077500000000000000000000000001467545753200207505ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/tests/__init__.py000066400000000000000000000000001467545753200230470ustar00rootroot00000000000000django-allauth-65.0.2/allauth/account/tests/test_adapter.py000066400000000000000000000013531467545753200240030ustar00rootroot00000000000000from django.http import HttpResponseRedirect from django.urls import reverse from allauth.account.adapter import DefaultAccountAdapter from allauth.core.exceptions import ImmediateHttpResponse class PreLoginRedirectAccountAdapter(DefaultAccountAdapter): def pre_login(self, *args, **kwargs): raise ImmediateHttpResponse(HttpResponseRedirect("/foo")) def test_adapter_pre_login(settings, user, user_password, client): settings.ACCOUNT_ADAPTER = ( "allauth.account.tests.test_adapter.PreLoginRedirectAccountAdapter" ) resp = client.post( reverse("account_login"), {"login": user.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == "/foo" django-allauth-65.0.2/allauth/account/tests/test_ajax.py000066400000000000000000000042311467545753200233040ustar00rootroot00000000000000import json from django.conf import settings from django.urls import reverse import pytest from pytest_django.asserts import assertRedirects from allauth.account import app_settings @pytest.mark.parametrize( "headers,ajax_expected", [ ({}, False), ({"HTTP_X_REQUESTED_WITH": "XMLHttpRequest"}, True), ({"HTTP_ACCEPT": "application/json"}, True), ], ) def test_ajax_headers(db, client, headers, ajax_expected): resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.org", "email2": "john@example.org", "password1": "johndoe", "password2": "johndoe", }, **headers, ) if ajax_expected: assert resp.status_code == 200 assert resp.json()["location"] == settings.LOGIN_REDIRECT_URL assert resp.json()["location"] == settings.LOGIN_REDIRECT_URL else: assert resp.status_code == 302 assertRedirects( resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False ) def test_ajax_password_reset(client, user, mailoutbox): resp = client.post( reverse("account_reset_password"), data={"email": user.email}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert len(mailoutbox) == 1 assert mailoutbox[0].to == [user.email] assert resp["content-type"] == "application/json" def test_ajax_login_fail(client, db): resp = client.post( reverse("account_login"), {}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert resp.status_code == 400 json.loads(resp.content.decode("utf8")) # TODO: Actually test something def test_ajax_login_success(settings, user, user_password, client): settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.OPTIONAL resp = client.post( reverse("account_login"), {"login": user.username, "password": user_password}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert resp.status_code == 200 data = json.loads(resp.content.decode("utf8")) assert data["location"] == "/accounts/profile/" django-allauth-65.0.2/allauth/account/tests/test_auth_backends.py000066400000000000000000000043651467545753200251640ustar00rootroot00000000000000from django.contrib.auth import get_user_model from django.test.utils import override_settings from allauth.account import app_settings from allauth.account.auth_backends import AuthenticationBackend from allauth.tests import TestCase class AuthenticationBackendTests(TestCase): def setUp(self): user = get_user_model().objects.create( is_active=True, email="john@example.com", username="john" ) user.set_password(user.username) user.save() self.user = user @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME ) # noqa def test_auth_by_username(self): user = self.user backend = AuthenticationBackend() self.assertEqual( backend.authenticate( request=None, username=user.username, password=user.username ).pk, user.pk, ) self.assertEqual( backend.authenticate( request=None, username=user.email, password=user.username ), None, ) @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.EMAIL ) # noqa def test_auth_by_email(self): user = self.user backend = AuthenticationBackend() self.assertEqual( backend.authenticate( request=None, username=user.email, password=user.username ).pk, user.pk, ) self.assertEqual( backend.authenticate( request=None, username=user.username, password=user.username ), None, ) @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME_EMAIL ) # noqa def test_auth_by_username_or_email(self): user = self.user backend = AuthenticationBackend() self.assertEqual( backend.authenticate( request=None, username=user.email, password=user.username ).pk, user.pk, ) self.assertEqual( backend.authenticate( request=None, username=user.username, password=user.username ).pk, user.pk, ) django-allauth-65.0.2/allauth/account/tests/test_change_email.py000066400000000000000000000361541467545753200247660ustar00rootroot00000000000000import json from unittest.mock import patch from django.contrib.auth import get_user_model from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateNotUsed, assertTemplateUsed from allauth.account.app_settings import AuthenticationMethod from allauth.account.models import EmailAddress, EmailConfirmationHMAC from allauth.account.utils import user_email def test_ajax_get(auth_client, user): primary = EmailAddress.objects.filter(user=user).first() secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=False, primary=False ) resp = auth_client.get( reverse("account_email"), HTTP_X_REQUESTED_WITH="XMLHttpRequest" ) data = json.loads(resp.content.decode("utf8")) assert data["data"] == [ { "id": primary.pk, "email": primary.email, "primary": True, "verified": True, }, { "id": secondary.pk, "email": secondary.email, "primary": False, "verified": False, }, ] def test_ajax_add(auth_client): resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) data = json.loads(resp.content.decode("utf8")) assert data["location"] == reverse("account_email") def test_ajax_add_invalid(auth_client): resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3#example.org"}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) data = json.loads(resp.content.decode("utf8")) assert "valid" in data["form"]["fields"]["email"]["errors"][0] def test_ajax_remove_primary(auth_client, user, settings): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" resp = auth_client.post( reverse("account_email"), {"action_remove": "", "email": user.email}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assertTemplateUsed(resp, "account/messages/cannot_delete_primary_email.txt") data = json.loads(resp.content.decode("utf8")) assert data["location"] == reverse("account_email") def test_remove_secondary(auth_client, user, settings, mailoutbox): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=False, primary=False ) resp = auth_client.post( reverse("account_email"), {"action_remove": "", "email": secondary.email}, ) assert not EmailAddress.objects.filter(pk=secondary.pk).exists() assertTemplateUsed(resp, "account/messages/email_deleted.txt") assert len(mailoutbox) == 1 assert f"{secondary.email} has been removed" in mailoutbox[0].body def test_set_primary_unverified(auth_client, user): secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=False, primary=False ) resp = auth_client.post( reverse("account_email"), {"action_primary": "", "email": secondary.email}, ) primary = EmailAddress.objects.get(email=user.email) secondary.refresh_from_db() assert not secondary.primary assert primary.primary assertTemplateUsed(resp, "account/messages/unverified_primary_email.txt") def test_set_primary(auth_client, user): primary = EmailAddress.objects.get(email=user.email) secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=True, primary=False ) resp = auth_client.post( reverse("account_email"), {"action_primary": "", "email": secondary.email}, ) primary.refresh_from_db() secondary.refresh_from_db() assert not primary.primary assert secondary.primary assertTemplateUsed(resp, "account/messages/primary_email_set.txt") def test_verify(auth_client, user): secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=False, primary=False ) resp = auth_client.post( reverse("account_email"), {"action_send": "", "email": secondary.email}, ) assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") def test_verify_unknown_email(auth_client, user): auth_client.post( reverse("account_email"), {"action_send": "", "email": "email@unknown.org"}, ) # This unknown email address must not be implicitly added. assert EmailAddress.objects.filter(user=user).count() == 1 def test_add_with_two_limiter(auth_client, user, settings): EmailAddress.objects.create( email="secondary@email.org", user=user, verified=False, primary=False ) settings.ACCOUNT_MAX_EMAIL_ADDRESSES = 2 resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"} ) assertTemplateNotUsed(resp, "account/messages/email_confirmation_sent.txt") def test_add_with_none_limiter(auth_client, settings): settings.ACCOUNT_MAX_EMAIL_ADDRESSES = None resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"} ) assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") def test_add_with_zero_limiter(auth_client, settings): settings.ACCOUNT_MAX_EMAIL_ADDRESSES = 0 resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"} ) assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") @pytest.mark.parametrize("has_email_field", [True, False]) def test_set_email_as_primary_doesnt_override_existing_changes_on_the_user( db, has_email_field, settings ): if not has_email_field: settings.ACCOUNT_USER_MODEL_EMAIL_FIELD = None user = get_user_model().objects.create( username="@raymond.penners", first_name="Before Update" ) email = EmailAddress.objects.create( user=user, email="raymond.penners@example.com", primary=True, verified=True, ) updated_first_name = "Updated" get_user_model().objects.filter(id=user.id).update(first_name=updated_first_name) email.set_as_primary() user.refresh_from_db() assert user.first_name == updated_first_name def test_delete_email_changes_user_email(user_factory, client, email_factory): user = user_factory(email_verified=False) client.force_login(user) first_email = EmailAddress.objects.get(user=user) first_email.primary = False first_email.save() # other_unverified_email EmailAddress.objects.create( user=user, email=email_factory(), verified=False, primary=False ) other_verified_email = EmailAddress.objects.create( user=user, email=email_factory(), verified=True, primary=False ) assert user_email(user) == first_email.email resp = client.post( reverse("account_email"), {"action_remove": "", "email": first_email.email}, ) assert resp.status_code == 302 user.refresh_from_db() assert user_email(user) == other_verified_email.email def test_delete_email_wipes_user_email(user_factory, client): user = user_factory(email_verified=False) client.force_login(user) first_email = EmailAddress.objects.get(user=user) first_email.primary = False first_email.save() assert user_email(user) == first_email.email resp = client.post( reverse("account_email"), {"action_remove": "", "email": first_email.email}, ) assert resp.status_code == 302 user.refresh_from_db() assert user_email(user) == "" def test_change_email(user_factory, client, settings, mailoutbox): settings.ACCOUNT_CHANGE_EMAIL = True settings.ACCOUNT_EMAIL_CONFIRMATION_HMAC = True settings.ACCOUNT_EMAIL_NOTIFICATIONS = True user = user_factory(email_verified=True) client.force_login(user) current_email = EmailAddress.objects.get(user=user) resp = client.post( reverse("account_email"), {"action_add": "", "email": "change-to@this.org"}, ) assert resp.status_code == 302 assert len(mailoutbox) == 1 assert mailoutbox[0].subject == "[example.com] Please Confirm Your Email Address" new_email = EmailAddress.objects.get(email="change-to@this.org") key = EmailConfirmationHMAC(new_email).key with patch("allauth.account.signals.email_changed.send") as email_changed_mock: resp = client.post(reverse("account_confirm_email", args=[key])) assert resp.status_code == 302 assert not EmailAddress.objects.filter(pk=current_email.pk).exists() assert EmailAddress.objects.filter(user=user).count() == 1 new_email.refresh_from_db() assert new_email.verified assert new_email.primary assert email_changed_mock.called assert len(mailoutbox) == 2 assert mailoutbox[1].subject == "[example.com] Email Changed" assert mailoutbox[1].to == [user.email] def test_add(auth_client, user, settings): resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"}, ) EmailAddress.objects.get( email="john3@example.org", user=user, verified=False, primary=False, ) assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") def test_add_with_reauthentication(auth_client, user, user_password, settings): settings.ACCOUNT_REAUTHENTICATION_REQUIRED = True resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"}, ) assert not EmailAddress.objects.filter(email="john3@example.org").exists() assert resp.status_code == 302 assert ( resp["location"] == reverse("account_reauthenticate") + "?next=%2Faccounts%2Femail%2F" ) resp = auth_client.post(resp["location"], {"password": user_password}) assert EmailAddress.objects.filter(email="john3@example.org").exists() assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") assert resp.status_code == 302 assert resp["location"] == reverse("account_email") @pytest.mark.parametrize( "prevent_enumeration", [ False, True, "strict", ], ) def test_add_not_allowed( auth_client, user, settings, user_factory, prevent_enumeration ): settings.ACCOUNT_PREVENT_ENUMERATION = prevent_enumeration email = "inuse@byotheruser.com" user_factory(email=email) resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": email}, ) if prevent_enumeration: assert resp.status_code == 302 email_address = EmailAddress.objects.get( email=email, user=user, verified=False, primary=False, ) assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") key = EmailConfirmationHMAC(email_address).key resp = auth_client.post(reverse("account_confirm_email", args=[key])) assertTemplateUsed(resp, "account/messages/email_confirmation_failed.txt") assert resp.status_code == 302 email_address.refresh_from_db() assert not email_address.verified else: assert resp.status_code == 200 assert resp.context["form"].errors == { "email": ["A user is already registered with this email address."] } @pytest.mark.parametrize( "authentication_method,primary_email,secondary_emails,delete_email,success", [ (AuthenticationMethod.EMAIL, "pri@ma.il", ["sec@ma.il"], "pri@ma.il", False), (AuthenticationMethod.EMAIL, "pri@ma.il", ["sec@ma.il"], "sec@ma.il", True), (AuthenticationMethod.EMAIL, "pri@ma.il", [], "pri@ma.il", False), (AuthenticationMethod.USERNAME, "pri@ma.il", ["sec@ma.il"], "pri@ma.il", False), (AuthenticationMethod.USERNAME, "pri@ma.il", ["sec@ma.il"], "sec@ma.il", True), (AuthenticationMethod.USERNAME, "pri@ma.il", [], "pri@ma.il", True), ( AuthenticationMethod.USERNAME_EMAIL, "pri@ma.il", ["sec@ma.il"], "pri@ma.il", False, ), ( AuthenticationMethod.USERNAME_EMAIL, "pri@ma.il", ["sec@ma.il"], "sec@ma.il", True, ), (AuthenticationMethod.USERNAME_EMAIL, "pri@ma.il", [], "pri@ma.il", True), ], ) def test_remove_email( client, settings, user_factory, primary_email, secondary_emails, delete_email, authentication_method, success, ): settings.ACCOUNT_AUTHENTICATION_METHOD = authentication_method user = user_factory(email=primary_email) EmailAddress.objects.bulk_create( [ EmailAddress(user=user, email=email, primary=False, verified=False) for email in secondary_emails ] ) client.force_login(user) resp = client.post( reverse("account_email"), {"action_remove": "", "email": delete_email}, ) assert EmailAddress.objects.filter(email=delete_email).exists() == (not success) if not success: assertTemplateUsed(resp, "account/messages/cannot_delete_primary_email.txt") @pytest.mark.parametrize( "email,did_look_up", [ ("valid@email.org", True), ("not-an-email", False), ], ) def test_dont_lookup_invalid_email(auth_client, email, did_look_up): with patch("allauth.account.views.EmailAddress.objects.get_for_user") as gfu_mock: gfu_mock.side_effect = EmailAddress.DoesNotExist auth_client.post( reverse("account_email"), {"action_remove": "", "email": email}, ) assert gfu_mock.called == did_look_up def test_add_requires_reauthentication(settings, auth_client): settings.ACCOUNT_REAUTHENTICATION_REQUIRED = True resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"}, ) assert not EmailAddress.objects.filter(email="john3@example.org").exists() assert resp["location"].startswith(reverse("account_reauthenticate")) def test_remove_requires_reauthentication(auth_client, user, settings): settings.ACCOUNT_REAUTHENTICATION_REQUIRED = True secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=False, primary=False ) resp = auth_client.post( reverse("account_email"), {"action_remove": "", "email": secondary.email}, ) assert resp["location"].startswith(reverse("account_reauthenticate")) assert EmailAddress.objects.filter(pk=secondary.pk).exists() def test_set_primary_requires_reauthentication(auth_client, user, settings): settings.ACCOUNT_REAUTHENTICATION_REQUIRED = True primary = EmailAddress.objects.get(email=user.email) secondary = EmailAddress.objects.create( email="secondary@email.org", user=user, verified=True, primary=False ) resp = auth_client.post( reverse("account_email"), {"action_primary": "", "email": secondary.email}, ) assert resp["location"].startswith(reverse("account_reauthenticate")) primary.refresh_from_db() secondary.refresh_from_db() assert primary.primary assert not secondary.primary django-allauth-65.0.2/allauth/account/tests/test_change_password.py000066400000000000000000000055101467545753200255310ustar00rootroot00000000000000from django.urls import reverse, reverse_lazy import pytest def test_change_unusable_password_redirects_to_set(client, user, user_password): user.set_unusable_password() user.save() client.force_login(user) resp = client.get(reverse("account_change_password")) assert resp.status_code == 302 assert resp["location"] == reverse("account_set_password") def test_set_usable_password_redirects_to_change(auth_client, user): resp = auth_client.get(reverse("account_set_password")) assert resp.status_code == 302 assert resp["location"] == reverse("account_change_password") @pytest.mark.parametrize( "logout,next_url,redirect_chain", [ (False, "", [(reverse_lazy("account_change_password"), 302)]), (False, "/foo", [("/foo", 302)]), ( True, "", [ (reverse_lazy("account_change_password"), 302), ( "/accounts/login/?next=/accounts/password/change/", 302, ), ], ), (True, "/foo", [("/foo", 302)]), ], ) def test_set_password( client, user, next_url, password_factory, logout, settings, redirect_chain ): settings.ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = logout user.set_unusable_password() user.save() client.force_login(user) password = password_factory() data = {"password1": password, "password2": password} if next_url: data["next"] = next_url resp = client.post( reverse("account_set_password"), data, follow=True, ) assert resp.redirect_chain == redirect_chain @pytest.mark.parametrize( "logout,next_url,redirect_chain", [ (False, "", [(reverse_lazy("account_change_password"), 302)]), (False, "/foo", [("/foo", 302)]), ( True, "", [ (reverse_lazy("account_change_password"), 302), ( "/accounts/login/?next=/accounts/password/change/", 302, ), ], ), (True, "/foo", [("/foo", 302)]), ], ) def test_change_password( auth_client, user, user_password, next_url, password_factory, logout, settings, redirect_chain, mailoutbox, ): settings.ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = logout settings.ACCOUNT_EMAIL_NOTIFICATIONS = True password = password_factory() data = {"oldpassword": user_password, "password1": password, "password2": password} if next_url: data["next"] = next_url resp = auth_client.post( reverse("account_change_password"), data, follow=True, ) assert resp.redirect_chain == redirect_chain assert len(mailoutbox) == 1 assert "Your password has been changed" in mailoutbox[0].body django-allauth-65.0.2/allauth/account/tests/test_commands.py000066400000000000000000000003561467545753200241660ustar00rootroot00000000000000from django.core.management import call_command def test_unset_multipleprimaryemails(db): # This command needs to be dropped, in favor of having a conditional # constraint. call_command("account_unsetmultipleprimaryemails") django-allauth-65.0.2/allauth/account/tests/test_decorators.py000066400000000000000000000022361467545753200245310ustar00rootroot00000000000000from django.urls import reverse from pytest_django.asserts import assertTemplateUsed from allauth.account.decorators import verified_email_required def test_verified_email_required(user_factory, request_factory): user = user_factory(email_verified=False) @verified_email_required def view(request): raise AssertionError() request = request_factory.get("/") request.user = user view(request) assertTemplateUsed("account/verified_email_required.html") def test_secure_admin_login_skips_admin_login_next(client): """ Test that we're not using 'next=/admin/login%2Fnext=/foo' """ resp = client.get(reverse("admin:login") + "?next=/foo") assert resp["location"] == "/accounts/login/?next=%2Ffoo" def test_secure_admin_login_denies_regular_users(auth_client): resp = auth_client.get(reverse("admin:login")) assert resp.status_code == 403 def test_secure_admin_login_passes_staff(auth_client, user): user.is_staff = True user.is_superuser = True user.save(update_fields=["is_staff", "is_superuser"]) resp = auth_client.get(reverse("admin:auth_user_changelist")) assert resp.status_code == 200 django-allauth-65.0.2/allauth/account/tests/test_email_verification.py000066400000000000000000000273161467545753200262230ustar00rootroot00000000000000from datetime import timedelta from unittest.mock import Mock from django.contrib.auth import SESSION_KEY, get_user_model from django.core.cache import cache from django.urls import reverse from django.utils.timezone import now import pytest from pytest_django.asserts import ( assertRedirects, assertTemplateNotUsed, assertTemplateUsed, ) from allauth.account import app_settings from allauth.account.adapter import DefaultAccountAdapter from allauth.account.models import ( EmailAddress, EmailConfirmation, EmailConfirmationHMAC, ) from allauth.account.signals import user_logged_in class TestEmailVerificationAdapter(DefaultAccountAdapter): SIGNUP_REDIRECT_URL = "/foobar" def get_signup_redirect_url(self, request): return self.SIGNUP_REDIRECT_URL @pytest.mark.parametrize( "adapter,query,expected_location", [ (None, "", app_settings.SIGNUP_REDIRECT_URL), (None, "?next=/foo", "/foo"), ( "allauth.account.tests.test_email_verification.TestEmailVerificationAdapter", "", TestEmailVerificationAdapter.SIGNUP_REDIRECT_URL, ), ], ) def test_login_on_verification( adapter, client, db, query, expected_location, password_factory, settings ): settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.MANDATORY settings.ACCOUNT_EMAIL_CONFIRMATION_HMAC = True settings.ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True if adapter: settings.ACCOUNT_ADAPTER = adapter password = password_factory() resp = client.post( reverse("account_signup"), data={ "username": "john", "email": "a@a.com", "password1": password, "password2": password, }, ) assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") resp = client.get(resp["location"]) assert resp.status_code == 200 email = EmailAddress.objects.get(email="a@a.com") key = EmailConfirmationHMAC(email).key receiver_mock = Mock() # we've logged if signal was called user_logged_in.connect(receiver_mock) resp = client.post(reverse("account_confirm_email", args=[key]) + query) assert resp["location"] == expected_location email = EmailAddress.objects.get(pk=email.pk) assert email.verified receiver_mock.assert_called_once_with( sender=get_user_model(), request=resp.wsgi_request, response=resp, user=email.user, signal=user_logged_in, ) user_logged_in.disconnect(receiver_mock) def test_email_verification_failed(settings, user_factory, client): settings.ACCOUNT_EMAIL_CONFIRMATION_HMAC = False user_factory(email_verified=True, email="foo@bar.org") unverified_user = user_factory(email_verified=False, email="foo@bar.org") email_address = EmailAddress.objects.get_for_user( unverified_user, unverified_user.email ) assert not email_address.verified confirmation = EmailConfirmation.objects.create( email_address=email_address, key="dummy", sent=now(), ) resp = client.post(reverse("account_confirm_email", args=[confirmation.key])) assertTemplateUsed(resp, "account/messages/email_confirmation_failed.txt") def test_email_verification_mandatory(settings, db, client, mailoutbox, enable_cache): settings.ACCOUNT_EMAIL_CONFIRMATION_HMAC = False settings.ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN = 10 settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.MANDATORY # Signup resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.com", "password1": "johndoe", "password2": "johndoe", }, follow=True, ) assert resp.status_code == 200 assert mailoutbox[0].to == ["john@example.com"] assert mailoutbox[0].body.find("http://") > 0 assert len(mailoutbox) == 1 assertTemplateUsed( resp, "account/verification_sent.%s" % app_settings.TEMPLATE_EXTENSION, ) # Attempt to login, unverified for attempt in [1, 2]: resp = client.post( reverse("account_login"), {"login": "johndoe", "password": "johndoe"}, follow=True, ) # is_active is controlled by the admin to manually disable # users. I don't want this flag to flip automatically whenever # users verify their email addresses. assert ( get_user_model().objects.filter(username="johndoe", is_active=True).exists() ) assertTemplateUsed( resp, "account/verification_sent." + app_settings.TEMPLATE_EXTENSION, ) # Attempt 1: no mail is sent due to cool-down , # but there was already a mail in the outbox. assert len(mailoutbox) == attempt assert ( EmailConfirmation.objects.filter( email_address__email="john@example.com" ).count() == attempt ) # Wait for cooldown -- wipe cache (incl. rate limits) cache.clear() # if we don't wipe the session, login will redirect to pending stage... client.logout() # Verify, and re-attempt to login. confirmation = EmailConfirmation.objects.filter( email_address__user__username="johndoe" )[:1].get() resp = client.get(reverse("account_confirm_email", args=[confirmation.key])) assertTemplateUsed( resp, "account/email_confirm.%s" % app_settings.TEMPLATE_EXTENSION ) client.post(reverse("account_confirm_email", args=[confirmation.key])) resp = client.post( reverse("account_login"), {"login": "johndoe", "password": "johndoe"}, ) assertRedirects(resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False) def test_optional_email_verification(settings, client, db, mailoutbox): settings.ACCOUNT_SIGNUP_REDIRECT_URL = "/accounts/welcome/" settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.OPTIONAL settings.ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False # Signup client.get(reverse("account_signup")) resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.com", "password1": "johndoe", }, ) # Logged in assertRedirects( resp, settings.ACCOUNT_SIGNUP_REDIRECT_URL, fetch_redirect_response=False ) assert mailoutbox[0].to == ["john@example.com"] assert len(mailoutbox) == 1 # Logout & login again client.logout() # Wait for cooldown EmailConfirmation.objects.update(sent=now() - timedelta(days=1)) # Signup resp = client.post( reverse("account_login"), {"login": "johndoe", "password": "johndoe"}, ) assertRedirects(resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False) assert mailoutbox[0].to == ["john@example.com"] # There was an issue that we sent out email confirmation mails # on each login in case of optional verification. Make sure # this is not the case: assert len(mailoutbox) == 1 def test_email_verification_hmac(settings, client, user_factory, mailoutbox, rf): settings.ACCOUNT_EMAIL_CONFIRMATION_HMAC = True user = user_factory(email_verified=False) email = EmailAddress.objects.get_for_user(user, user.email) confirmation = EmailConfirmationHMAC(email) request = rf.get("/") confirmation.send(request=request) assert len(mailoutbox) == 1 client.post(reverse("account_confirm_email", args=[confirmation.key])) email = EmailAddress.objects.get(pk=email.pk) assert email.verified def test_email_verification_hmac_timeout( settings, user_factory, client, mailoutbox, rf ): settings.ACCOUNT_EMAIL_CONFIRMATION_HMAC = True settings.ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 0 user = user_factory(email_verified=False) email = EmailAddress.objects.get_for_user(user, user.email) confirmation = EmailConfirmationHMAC(email) request = rf.get("/") confirmation.send(request=request) assert len(mailoutbox) == 1 client.post(reverse("account_confirm_email", args=[confirmation.key])) email = EmailAddress.objects.get(pk=email.pk) assert not email.verified def test_verify_email_with_another_user_logged_in( settings, user_factory, client, mailoutbox ): """Test the email verification view. If User B clicks on an email verification link while logged in as User A, ensure User A gets logged out.""" settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL user = user_factory(email_verified=False) client.force_login(user) client.post(reverse("account_email"), {"email": user.email, "action_send": ""}) assert len(mailoutbox) == 1 assert mailoutbox[0].to == [user.email] client.logout() body = mailoutbox[0].body assert body.find("http://") > 0 user2 = user_factory(email_verified=False, password="doe") resp = client.post( reverse("account_login"), { "login": user2.email, "password": "doe", }, ) assert user2 == resp.context["user"] url = body[body.find("/accounts/confirm-email/") :].split()[0] resp = client.post(url) assertTemplateUsed(resp, "account/messages/logged_out.txt") assertTemplateUsed(resp, "account/messages/email_confirmed.txt") assertRedirects(resp, settings.LOGIN_URL, fetch_redirect_response=False) def test_verify_email_with_same_user_logged_in( settings, user_factory, client, mailoutbox ): """If the user clicks on an email verification link while logged in, ensure the user stays logged in. """ settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL user = user_factory(email_verified=False) client.force_login(user) client.post(reverse("account_email"), {"email": user.email, "action_send": ""}) assert len(mailoutbox) == 1 assert mailoutbox[0].to == [user.email] body = mailoutbox[0].body assert body.find("http://") > 0 url = body[body.find("/accounts/confirm-email/") :].split()[0] resp = client.post(url) assertTemplateNotUsed(resp, "account/messages/logged_out.txt") assertTemplateUsed(resp, "account/messages/email_confirmed.txt") assertRedirects(resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False) assert user == resp.wsgi_request.user def test_verify_logs_out_user(auth_client, settings, user, user_factory): """ When a user is signed in, and you follow an email confirmation link of another user within the same browser/session, be sure to sign out the signed in user. """ settings.ACCOUNT_CONFIRM_EMAIL_ON_GET = False confirming_user = user_factory(email_verified=False) assert auth_client.session[SESSION_KEY] == str(user.pk) email = EmailAddress.objects.get(user=confirming_user, verified=False) auth_client.get( reverse( "account_confirm_email", kwargs={"key": EmailConfirmationHMAC(email).key} ) ) assert not auth_client.session.get(SESSION_KEY) def test_email_verification_login_redirect(client, db, settings, password_factory): settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.MANDATORY password = password_factory() resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "user@email.org", "password1": password, "password2": password, }, ) assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") resp = client.get(reverse("account_login")) assert resp.status_code == 200 django-allauth-65.0.2/allauth/account/tests/test_email_verification_by_code.py000066400000000000000000000150611467545753200277010ustar00rootroot00000000000000import re from unittest.mock import patch from django.conf import settings from django.contrib.auth import get_user_model from django.test import Client from django.urls import reverse import pytest from allauth.account.internal.flows import email_verification_by_code from allauth.account.models import EmailAddress @pytest.fixture def get_last_code(client, mailoutbox): def f(): code = re.search( "\n[0-9a-z]{6}\n", mailoutbox[0].body, re.I | re.DOTALL | re.MULTILINE )[0].strip() assert ( client.session[ email_verification_by_code.EMAIL_VERIFICATION_CODE_SESSION_KEY ]["code"] == code ) return code return f @pytest.fixture(autouse=True) def email_verification_settings(settings): settings.ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_AUTHENTICATION_METHOD = "email" return settings @pytest.mark.parametrize( "query,expected_url", [ ("", settings.LOGIN_REDIRECT_URL), ("?next=/foo", "/foo"), ], ) def test_signup( client, db, settings, password_factory, get_last_code, query, expected_url ): password = password_factory() resp = client.post( reverse("account_signup") + query, { "username": "johndoe", "email": "john@example.com", "password1": password, "password2": password, }, ) assert get_user_model().objects.filter(username="johndoe").count() == 1 code = get_last_code() assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") resp = client.get(reverse("account_email_verification_sent")) assert resp.status_code == 200 resp = client.post(reverse("account_email_verification_sent"), data={"code": code}) assert resp.status_code == 302 assert resp["location"] == expected_url def test_signup_prevent_enumeration( client, db, settings, password_factory, user, mailoutbox ): password = password_factory() resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": user.email, "password1": password, "password2": password, }, ) assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") assert not get_user_model().objects.filter(username="johndoe").exists() assert mailoutbox[0].subject == "[example.com] Account Already Exists" resp = client.get(reverse("account_email_verification_sent")) assert resp.status_code == 200 resp = client.post(reverse("account_email_verification_sent"), data={"code": ""}) assert resp.status_code == 200 assert resp.context["form"].errors == {"code": ["This field is required."]} resp = client.post(reverse("account_email_verification_sent"), data={"code": "123"}) assert resp.status_code == 200 assert resp.context["form"].errors == {"code": ["Incorrect code."]} # Max attempts resp = client.post(reverse("account_email_verification_sent"), data={"code": "456"}) assert resp.status_code == 302 assert resp["location"] == reverse("account_login") @pytest.mark.parametrize("change_email", (False, True)) def test_add_or_change_email(auth_client, user, get_last_code, change_email, settings): settings.ACCOUNT_CHANGE_EMAIL = change_email email = "additional@email.org" assert EmailAddress.objects.filter(user=user).count() == 1 with patch("allauth.account.signals.email_added") as email_added_signal: with patch("allauth.account.signals.email_changed") as email_changed_signal: resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": email} ) assert resp["location"] == reverse("account_email_verification_sent") assert not email_added_signal.send.called assert not email_changed_signal.send.called assert EmailAddress.objects.filter(email=email).count() == 0 code = get_last_code() resp = auth_client.get(reverse("account_email_verification_sent")) assert resp.status_code == 200 with patch("allauth.account.signals.email_added") as email_added_signal: with patch("allauth.account.signals.email_changed") as email_changed_signal: with patch( "allauth.account.signals.email_confirmed" ) as email_confirmed_signal: resp = auth_client.post( reverse("account_email_verification_sent"), data={"code": code} ) assert resp.status_code == 302 assert resp["location"] == reverse("account_email") assert email_added_signal.send.called assert email_confirmed_signal.send.called assert email_changed_signal.send.called == change_email assert EmailAddress.objects.filter(email=email, verified=True).count() == 1 assert EmailAddress.objects.filter(user=user).count() == (1 if change_email else 2) def test_email_verification_login_redirect( client, db, settings, password_factory, email_verification_settings ): password = password_factory() resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "user@email.org", "password1": password, "password2": password, }, ) assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") resp = client.get(reverse("account_login")) assert resp["location"] == reverse("account_email_verification_sent") def test_email_verification_rate_limits( db, user_password, email_verification_settings, settings, user_factory, password_factory, enable_cache, ): settings.ACCOUNT_RATE_LIMITS = {"confirm_email": "1/m/key"} email = "user@email.org" user_factory(email=email, email_verified=False, password=user_password) for attempt in range(2): resp = Client().post( reverse("account_login"), { "login": email, "password": user_password, }, ) if attempt == 0: assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") else: assert resp.status_code == 200 assert resp.context["form"].errors == { "__all__": ["Too many failed login attempts. Try again later."] } django-allauth-65.0.2/allauth/account/tests/test_login.py000066400000000000000000000311341467545753200234730ustar00rootroot00000000000000import json from unittest.mock import ANY, patch from django.conf import settings from django.contrib.auth import get_user_model from django.core import mail from django.test.utils import override_settings from django.urls import NoReverseMatch, reverse from pytest_django.asserts import assertTemplateUsed from allauth.account import app_settings from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.account.forms import LoginForm from allauth.account.models import EmailAddress from allauth.tests import TestCase @override_settings( ACCOUNT_DEFAULT_HTTP_PROTOCOL="https", ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY, ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME, ACCOUNT_SIGNUP_FORM_CLASS=None, ACCOUNT_EMAIL_SUBJECT_PREFIX=None, LOGIN_REDIRECT_URL="/accounts/profile/", ACCOUNT_SIGNUP_REDIRECT_URL="/accounts/welcome/", ACCOUNT_ADAPTER="allauth.account.adapter.DefaultAccountAdapter", ACCOUNT_USERNAME_REQUIRED=True, ) class LoginTests(TestCase): @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME_EMAIL ) def test_username_containing_at(self): user = get_user_model().objects.create(username="@raymond.penners") user.set_password("psst") user.save() EmailAddress.objects.create( user=user, email="raymond.penners@example.com", primary=True, verified=True, ) resp = self.client.post( reverse("account_login"), {"login": "@raymond.penners", "password": "psst"}, ) self.assertRedirects( resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False ) self.assertEqual( self.client.session[AUTHENTICATION_METHODS_SESSION_KEY], [ { "at": ANY, "username": "@raymond.penners", "method": "password", } ], ) def _create_user(self, username="john", password="doe", **kwargs): user = get_user_model().objects.create( username=username, is_active=True, **kwargs ) if password: user.set_password(password) else: user.set_unusable_password() user.save() return user def _create_user_and_login(self, usable_password=True): password = "doe" if usable_password else False user = self._create_user(password=password) self.client.force_login(user) return user def test_redirect_when_authenticated(self): self._create_user_and_login() c = self.client resp = c.get(reverse("account_login")) self.assertRedirects(resp, "/accounts/profile/", fetch_redirect_response=False) def test_ajax_password_change(self): self._create_user_and_login() resp = self.client.post( reverse("account_change_password"), data={ "oldpassword": "doe", "password1": "AbCdEf!123", "password2": "AbCdEf!123456", }, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) self.assertEqual(resp["content-type"], "application/json") data = json.loads(resp.content.decode("utf8")) assert "same password" in data["form"]["fields"]["password2"]["errors"][0] @override_settings( ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.OPTIONAL ) def test_login_unverified_account_optional(self): """Tests login behavior when email verification is optional.""" user = get_user_model().objects.create(username="john") user.set_password("doe") user.save() EmailAddress.objects.create( user=user, email="user@example.com", primary=True, verified=False ) resp = self.client.post( reverse("account_login"), {"login": "john", "password": "doe"} ) self.assertRedirects( resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False ) @override_settings( ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.OPTIONAL, ACCOUNT_LOGIN_ATTEMPTS_LIMIT=3, CACHES={ "default": { "BACKEND": "django.core.cache.backends.locmem.LocMemCache", } }, ) def test_login_failed_attempts_exceeded(self): user = get_user_model().objects.create(username="john") user.set_password("doe") user.save() EmailAddress.objects.create( user=user, email="user@example.com", primary=True, verified=False ) for i in range(5): is_valid_attempt = i == 4 is_locked = i >= 3 resp = self.client.post( reverse("account_login"), { "login": ["john", "John", "JOHN", "JOhn", "joHN"][i], "password": ("doe" if is_valid_attempt else "wrong"), }, ) self.assertFormError( resp.context["form"], None, ( "Too many failed login attempts. Try again later." if is_locked else "The username and/or password you specified are not correct." ), ) @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.EMAIL, ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY, ACCOUNT_LOGIN_ATTEMPTS_LIMIT=1, CACHES={ "default": { "BACKEND": "django.core.cache.backends.locmem.LocMemCache", } }, ) def test_login_failed_attempts_exceeded_cleared_on_password_reset(self): # Ensure that login attempts, once they hit the limit, # can use the password reset mechanism to regain access. user = get_user_model().objects.create( username="john", email="john@example.org", is_active=True ) user.set_password("doe") user.save() EmailAddress.objects.create( user=user, email="john@example.org", primary=True, verified=True ) resp = self.client.post( reverse("account_login"), {"login": user.email, "password": "bad"} ) self.assertFormError( resp.context["form"], None, "The email address and/or password you specified are not correct.", ) resp = self.client.post( reverse("account_login"), {"login": user.email, "password": "bad"} ) self.assertFormError( resp.context["form"], None, "Too many failed login attempts. Try again later.", ) self.client.post(reverse("account_reset_password"), data={"email": user.email}) body = mail.outbox[0].body self.assertGreater(body.find("https://"), 0) # Extract URL for `password_reset_from_key` view and access it url = body[body.find("/accounts/password/reset/") :].split()[0] resp = self.client.get(url) # Follow the redirect the actual password reset page with the key # hidden. url = resp.url resp = self.client.get(url) self.assertTemplateUsed( resp, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION, ) self.assertFalse("token_fail" in resp.context_data) new_password = "newpass123" # Reset the password resp = self.client.post( url, {"password1": new_password, "password2": new_password} ) self.assertRedirects(resp, reverse("account_reset_password_from_key_done")) # Check the new password is in effect user = get_user_model().objects.get(pk=user.pk) self.assertTrue(user.check_password(new_password)) resp = self.client.post( reverse("account_login"), {"login": user.email, "password": new_password}, ) self.assertRedirects( resp, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False ) @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.EMAIL, ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY, ACCOUNT_LOGIN_ATTEMPTS_LIMIT=1, ) def test_login_using_unverified_email_address_is_prohibited(self): user = get_user_model().objects.create( username="john", email="john@example.org", is_active=True ) user.set_password("doe") user.save() EmailAddress.objects.create( user=user, email="john@example.org", primary=True, verified=True ) EmailAddress.objects.create( user=user, email="john@example.com", primary=False, verified=False ) resp = self.client.post( reverse("account_login"), {"login": "john@example.com", "password": "doe"} ) self.assertRedirects( resp, reverse("account_email_verification_sent"), fetch_redirect_response=False, ) self.assertEqual(len(mail.outbox), 1) assert mail.outbox[0].to == ["john@example.com"] def test_login_unverified_account_mandatory(self): """Tests login behavior when email verification is mandatory.""" user = get_user_model().objects.create(username="john") user.set_password("doe") user.save() EmailAddress.objects.create( user=user, email="user@example.com", primary=True, verified=False ) resp = self.client.post( reverse("account_login"), {"login": "john", "password": "doe"} ) self.assertRedirects(resp, reverse("account_email_verification_sent")) def test_login_inactive_account(self): """ Tests login behavior with inactive accounts. Inactive user accounts should be prevented from performing any actions, regardless of their verified state. """ # Inactive and verified user account user = get_user_model().objects.create(username="john", is_active=False) user.set_password("doe") user.save() EmailAddress.objects.create( user=user, email="john@example.com", primary=True, verified=True ) resp = self.client.post( reverse("account_login"), {"login": "john", "password": "doe"} ) self.assertRedirects(resp, reverse("account_inactive")) # Inactive and unverified user account user = get_user_model().objects.create(username="doe", is_active=False) user.set_password("john") user.save() EmailAddress.objects.create( user=user, email="user@example.com", primary=True, verified=False ) resp = self.client.post( reverse("account_login"), {"login": "doe", "password": "john"} ) self.assertRedirects(resp, reverse("account_inactive")) @override_settings(ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS=False) def test_account_authenticated_login_redirects_is_false(self): self._create_user_and_login() resp = self.client.get(reverse("account_login")) self.assertEqual(resp.status_code, 200) def test_login_password_forgotten_link_not_present(client, db): with patch("allauth.account.forms.reverse") as reverse_mock: reverse_mock.side_effect = NoReverseMatch form = LoginForm() assert form.fields["password"].help_text == "" def test_login_password_forgotten_link_present(client, db): form = LoginForm() assert ( form.fields["password"].help_text == 'Forgot your password?' ) def test_login_while_authenticated(settings, client, user_factory): settings.ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS = False user_factory(username="john", email="john@example.org", password="doe") user_factory(username="jane", email="jane@example.org", password="doe") redirect_url = settings.LOGIN_REDIRECT_URL resp = client.post(reverse("account_login"), {"login": "john", "password": "doe"}) assert resp.status_code == 302 assert resp["location"] == redirect_url resp = client.post(reverse("account_login"), {"login": "jane", "password": "doe"}) assert resp.status_code == 302 assert resp["location"] == redirect_url def test_login_page(client, db): resp = client.get(reverse("account_login")) assert resp.status_code == 200 assertTemplateUsed(resp, "account/login.html") django-allauth-65.0.2/allauth/account/tests/test_login_by_code.py000066400000000000000000000102751467545753200251620ustar00rootroot00000000000000from unittest.mock import ANY from django.urls import reverse import pytest from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.account.internal.flows.login_by_code import LOGIN_CODE_STATE_KEY from allauth.account.internal.stagekit import LOGIN_SESSION_KEY from allauth.account.models import EmailAddress @pytest.fixture def request_login_by_code(mailoutbox): def f(client, email): resp = client.get(reverse("account_request_login_code") + "?next=/foo") assert resp.status_code == 200 assert b'value="/foo"' in resp.content resp = client.post( reverse("account_request_login_code"), data={"email": email, "next": "/foo"} ) assert resp.status_code == 302 assert ( resp["location"] == reverse("account_confirm_login_code") + "?next=%2Ffoo" ) assert len(mailoutbox) == 1 code = client.session[LOGIN_SESSION_KEY]["state"][LOGIN_CODE_STATE_KEY]["code"] assert len(code) == 6 assert code in mailoutbox[0].body return code return f def test_login_by_code(client, user, request_login_by_code): code = request_login_by_code(client, user.email) code_with_ws = " " + code[0:3] + " " + code[3:] resp = client.post( reverse("account_confirm_login_code"), data={"code": code_with_ws, "next": "/foo"}, ) assert resp.status_code == 302 assert LOGIN_SESSION_KEY not in client.session assert resp["location"] == "/foo" assert client.session[AUTHENTICATION_METHODS_SESSION_KEY][-1] == { "method": "code", "email": user.email, "at": ANY, } def test_login_by_code_max_attempts(client, user, request_login_by_code, settings): settings.ACCOUNT_LOGIN_BY_CODE_MAX_ATTEMPTS = 2 request_login_by_code(client, user.email) for i in range(3): resp = client.post( reverse("account_confirm_login_code"), data={"code": "wrong"} ) if i >= 1: assert resp.status_code == 302 assert resp["location"] == reverse("account_request_login_code") assert LOGIN_SESSION_KEY not in client.session else: assert resp.status_code == 200 assert LOGIN_SESSION_KEY in client.session assert resp.context["form"].errors == {"code": ["Incorrect code."]} def test_login_by_code_unknown_user(mailoutbox, client, db): resp = client.post( reverse("account_request_login_code"), data={"email": "unknown@email.org"}, ) assert resp.status_code == 302 assert resp["location"] == reverse("account_confirm_login_code") resp = client.post(reverse("account_confirm_login_code"), data={"code": "123456"}) @pytest.mark.parametrize( "setting,code_required", [ (True, True), ({"password"}, True), ({"socialaccount"}, False), ], ) def test_login_by_code_required( client, settings, user_factory, password_factory, setting, code_required ): password = password_factory() user = user_factory(password=password, email_verified=False) email_address = EmailAddress.objects.get(email=user.email) assert not email_address.verified settings.ACCOUNT_LOGIN_BY_CODE_REQUIRED = setting resp = client.post( reverse("account_login"), data={"login": user.username, "password": password}, ) assert resp.status_code == 302 if code_required: assert resp["location"] == reverse("account_confirm_login_code") code = client.session[LOGIN_SESSION_KEY]["state"][LOGIN_CODE_STATE_KEY]["code"] resp = client.get( reverse("account_confirm_login_code"), data={"login": user.username, "password": password}, ) assert resp.status_code == 200 resp = client.post(reverse("account_confirm_login_code"), data={"code": code}) email_address.refresh_from_db() assert email_address.verified assert resp["location"] == settings.LOGIN_REDIRECT_URL def test_login_by_code_redirect(client, user, request_login_by_code): request_login_by_code(client, user.email) resp = client.get(reverse("account_login")) assert resp["location"] == reverse("account_confirm_login_code") django-allauth-65.0.2/allauth/account/tests/test_logout.py000066400000000000000000000042751467545753200237020ustar00rootroot00000000000000from django.contrib.auth import get_user_model from django.core import validators from django.test.client import Client from django.test.utils import override_settings from django.urls import reverse from allauth.account import app_settings from allauth.account.signals import user_logged_out from allauth.tests import Mock, TestCase test_username_validators = [ validators.RegexValidator(regex=r"^[a-c]+$", message="not abc") ] @override_settings( ACCOUNT_DEFAULT_HTTP_PROTOCOL="https", ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY, ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME, ACCOUNT_SIGNUP_FORM_CLASS=None, ACCOUNT_EMAIL_SUBJECT_PREFIX=None, LOGIN_REDIRECT_URL="/accounts/profile/", ACCOUNT_SIGNUP_REDIRECT_URL="/accounts/welcome/", ACCOUNT_ADAPTER="allauth.account.adapter.DefaultAccountAdapter", ACCOUNT_USERNAME_REQUIRED=True, ) class LogoutTests(TestCase): @override_settings(ACCOUNT_LOGOUT_ON_GET=True) def test_logout_view_on_get(self): c, resp = self._logout_view("get") self.assertTemplateUsed(resp, "account/messages/logged_out.txt") @override_settings(ACCOUNT_LOGOUT_ON_GET=False) def test_logout_view_on_post(self): c, resp = self._logout_view("get") self.assertTemplateUsed( resp, "account/logout.%s" % app_settings.TEMPLATE_EXTENSION ) receiver_mock = Mock() user_logged_out.connect(receiver_mock) resp = c.post(reverse("account_logout")) self.assertTemplateUsed(resp, "account/messages/logged_out.txt") receiver_mock.assert_called_once_with( sender=get_user_model(), request=resp.wsgi_request, user=get_user_model().objects.get(username="john"), signal=user_logged_out, ) user_logged_out.disconnect(receiver_mock) def _logout_view(self, method): c = Client() user = get_user_model().objects.create(username="john", is_active=True) user.set_password("doe") user.save() c = Client() c.login(username="john", password="doe") return c, getattr(c, method)(reverse("account_logout")) django-allauth-65.0.2/allauth/account/tests/test_middleware.py000066400000000000000000000021521467545753200244760ustar00rootroot00000000000000import django from django.http import HttpResponse from django.test.client import AsyncClient from django.urls import path, reverse import pytest from allauth.account.internal.decorators import login_not_required from allauth.core.exceptions import ImmediateHttpResponse @login_not_required def raise_immediate_http_response(request): response = HttpResponse(content="raised-response") raise ImmediateHttpResponse(response=response) urlpatterns = [path("raise", raise_immediate_http_response)] def test_immediate_http_response(settings, client): settings.ROOT_URLCONF = "allauth.account.tests.test_middleware" resp = client.get("/raise") assert resp.content == b"raised-response" skip_django_lt_5 = pytest.mark.skipif( django.VERSION[0] < 5, reason="This test is allowed to fail on Django <5." ) @skip_django_lt_5 @pytest.mark.asyncio @pytest.mark.django_db(transaction=True) async def test_accounts_redirect_async_ctx(user, db): aclient = AsyncClient() await aclient.aforce_login(user) resp = await aclient.get("/accounts/") assert resp["location"] == reverse("account_email") django-allauth-65.0.2/allauth/account/tests/test_models.py000066400000000000000000000017021467545753200236440ustar00rootroot00000000000000import uuid from django.contrib.auth.models import AbstractUser from django.db import models from allauth.account.models import EmailAddress class UUIDUser(AbstractUser): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) class Meta(AbstractUser.Meta): # type: ignore[name-defined] swappable = "AUTH_USER_MODEL" def test_add_new_email(rf, user, settings): settings.ACCOUNT_CHANGE_EMAIL = True request = rf.get("/") assert EmailAddress.objects.filter(user=user).count() == 1 new_email = EmailAddress.objects.add_new_email(request, user, "new@email.org") assert not new_email.verified assert not new_email.primary assert EmailAddress.objects.filter(user=user).count() == 2 EmailAddress.objects.add_new_email(request, user, "new2@email.org") assert EmailAddress.objects.filter(user=user).count() == 2 new_email.refresh_from_db() assert new_email.email == "new2@email.org" django-allauth-65.0.2/allauth/account/tests/test_ratelimit.py000066400000000000000000000007111467545753200243520ustar00rootroot00000000000000from django.urls import reverse def test_case_insensitive_password_reset(settings, enable_cache, user_factory, client): settings.ACCOUNT_RATE_LIMITS = {"reset_password": "1/m"} user_factory(email="a@b.com") resp = client.post(reverse("account_reset_password"), data={"email": "a@b.com"}) assert resp.status_code == 302 resp = client.post(reverse("account_reset_password"), data={"email": "A@B.COM"}) assert resp.status_code == 429 django-allauth-65.0.2/allauth/account/tests/test_reauthentication.py000066400000000000000000000047321467545753200257350ustar00rootroot00000000000000from unittest.mock import ANY from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth import app_settings as allauth_settings from allauth.account.adapter import get_adapter from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY @pytest.mark.parametrize( "with_totp,with_password,expected_method_urlnames", [ (False, True, ["account_reauthenticate"]), (True, True, ["account_reauthenticate", "mfa_reauthenticate"]), (True, False, ["mfa_reauthenticate"]), ], ) def test_user_with_mfa_only( user_factory, with_totp, with_password, expected_method_urlnames, client ): if not allauth_settings.MFA_ENABLED and with_totp: return user = user_factory(with_totp=with_totp, password=None if with_password else "!") assert user.has_usable_password() == with_password client.force_login(user) methods = get_adapter().get_reauthentication_methods(user) assert len(methods) == len(expected_method_urlnames) assert set([m["url"] for m in methods]) == set( map(reverse, expected_method_urlnames) ) for urlname in ["account_reauthenticate", "mfa_reauthenticate"]: if urlname == "mfa_reauthenticate" and not allauth_settings.MFA_ENABLED: continue resp = client.get(reverse(urlname) + "?next=/foo") if urlname in expected_method_urlnames: assert resp.status_code == 200 else: assert resp.status_code == 302 assert "next=%2Ffoo" in resp["location"] def test_reauthentication(settings, auth_client, user_password): settings.ACCOUNT_REAUTHENTICATION_REQUIRED = True resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"}, ) assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.get(reverse("account_reauthenticate")) assertTemplateUsed(resp, "account/reauthenticate.html") resp = auth_client.post( reverse("account_reauthenticate"), data={"password": user_password} ) assert resp.status_code == 302 resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "john3@example.org"}, ) assert resp["location"].startswith(reverse("account_email")) methods = auth_client.session[AUTHENTICATION_METHODS_SESSION_KEY] assert methods[-1] == {"method": "password", "at": ANY, "reauthenticated": True} django-allauth-65.0.2/allauth/account/tests/test_reset_password.py000066400000000000000000000313751467545753200254360ustar00rootroot00000000000000import json from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.core import mail from django.test.utils import override_settings from django.urls import reverse, reverse_lazy from django.utils.http import urlencode import pytest from pytest_django.asserts import assertRedirects, assertTemplateUsed from allauth.account import app_settings from allauth.account.forms import ResetPasswordForm, default_token_generator from allauth.account.models import EmailAddress from allauth.account.utils import user_pk_to_url_str from allauth.tests import TestCase @pytest.fixture def password_reset_url(): def f(user): temp_key = default_token_generator.make_token(user) uid = user_pk_to_url_str(user) return reverse( "account_reset_password_from_key", kwargs={"uidb36": uid, "key": temp_key} ) return f @pytest.mark.django_db def test_reset_password_unknown_account(client, settings): settings.ACCOUNT_PREVENT_ENUMERATION = True client.post( reverse("account_reset_password"), data={"email": "unknown@example.org"}, ) assert len(mail.outbox) == 1 assert mail.outbox[0].to == ["unknown@example.org"] @pytest.mark.django_db def test_reset_password_unknown_account_disabled(client, settings): settings.ACCOUNT_PREVENT_ENUMERATION = True settings.ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False client.post( reverse("account_reset_password"), data={"email": "unknown@example.org"}, ) assert len(mail.outbox) == 0 @pytest.mark.parametrize( "query,expected_location", [("", reverse_lazy("account_reset_password_done")), ("?next=/foo", "/foo")], ) def test_reset_password_next_url(client, user, query, expected_location): resp = client.post( reverse("account_reset_password") + query, data={"email": user.email}, ) assert resp["location"] == expected_location @override_settings( ACCOUNT_PREVENT_ENUMERATION=False, ACCOUNT_DEFAULT_HTTP_PROTOCOL="https", ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY, ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME, ACCOUNT_SIGNUP_FORM_CLASS=None, ACCOUNT_EMAIL_SUBJECT_PREFIX=None, LOGIN_REDIRECT_URL="/accounts/profile/", ACCOUNT_SIGNUP_REDIRECT_URL="/accounts/welcome/", ACCOUNT_ADAPTER="allauth.account.adapter.DefaultAccountAdapter", ACCOUNT_USERNAME_REQUIRED=True, ACCOUNT_EMAIL_NOTIFICATIONS=True, ) class ResetPasswordTests(TestCase): def test_user_email_not_sent_inactive_user(self): User = get_user_model() User.objects.create_user( "mike123", "mike@ixample.org", "test123", is_active=False ) data = {"email": "mike@ixample.org"} form = ResetPasswordForm(data) self.assertFalse(form.is_valid()) def test_password_reset_get(self): resp = self.client.get(reverse("account_reset_password")) self.assertTemplateUsed(resp, "account/password_reset.html") def test_set_password_not_allowed(self): user = self._create_user_and_login(True) pwd = "!*123i1uwn12W23" self.assertFalse(user.check_password(pwd)) resp = self.client.post( reverse("account_set_password"), data={"password1": pwd, "password2": pwd}, ) user.refresh_from_db() self.assertFalse(user.check_password(pwd)) self.assertTrue(user.has_usable_password()) self.assertEqual(resp.status_code, 302) def test_password_forgotten_username_hint(self): user = self._request_new_password() body = mail.outbox[0].body assert user.username in body @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.EMAIL ) def test_password_forgotten_no_username_hint(self): user = self._request_new_password() body = mail.outbox[0].body assert user.username not in body def _request_new_password(self): user = get_user_model().objects.create( username="john", email="john@example.org", is_active=True ) user.set_password("doe") user.save() self.client.post( reverse("account_reset_password"), data={"email": "john@example.org"}, ) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].to, ["john@example.org"]) return user def test_password_reset_flow_with_empty_session(self): """ Test the password reset flow when the session is empty: requesting a new password, receiving the reset link via email, following the link, getting redirected to the new link (without the token) Copying the link and using it in a DIFFERENT client (Browser/Device). """ # Request new password self._request_new_password() body = mail.outbox[0].body self.assertGreater(body.find("https://"), 0) # Extract URL for `password_reset_from_key` view url = body[body.find("/accounts/password/reset/") :].split()[0] resp = self.client.get(url) reset_pass_url = resp.url # Accessing the url via a different session resp = self.client_class().get(reset_pass_url) # We should receive the token_fail context_data self.assertTemplateUsed( resp, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION, ) self.assertTrue(resp.context_data["token_fail"]) @override_settings( ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.EMAIL ) def test_password_reset_flow_with_another_user_logged_in(self): """ Tests the password reset flow: if User B requested a password reset earlier and now User A is logged in, User B now clicks on the link, ensure User A is logged out before continuing. """ # Request new password self._request_new_password() body = mail.outbox[0].body self.assertGreater(body.find("https://"), 0) user2 = self._create_user(username="john2", email="john2@example.com") EmailAddress.objects.create( user=user2, email=user2.email, primary=True, verified=True ) resp = self.client.post( reverse("account_login"), { "login": user2.email, "password": "doe", }, ) self.assertEqual(user2, resp.context["user"]) # Extract URL for `password_reset_from_key` view and access it url = body[body.find("/accounts/password/reset/") :].split()[0] resp = self.client.get(url) # Follow the redirect the actual password reset page with the key # hidden. url = resp.url resp = self.client.get(url) self.assertTemplateUsed( resp, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION ) self.assertFalse("token_fail" in resp.context_data) # Reset the password resp = self.client.post( url, {"password1": "newpass123", "password2": "newpass123"}, follow=True ) self.assertRedirects(resp, reverse("account_reset_password_from_key_done")) self.assertNotEqual(user2, resp.context["user"]) self.assertEqual(AnonymousUser(), resp.context["user"]) def test_password_reset_flow_with_email_changed(self): """ Test that the password reset token is invalidated if the user email address was changed. """ user = self._request_new_password() body = mail.outbox[0].body self.assertGreater(body.find("https://"), 0) EmailAddress.objects.create(user=user, email="other@email.org") # Extract URL for `password_reset_from_key` view url = body[body.find("/accounts/password/reset/") :].split()[0] resp = self.client.get(url) self.assertTemplateUsed( resp, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION, ) self.assertTrue("token_fail" in resp.context_data) @override_settings(ACCOUNT_LOGIN_ON_PASSWORD_RESET=True) def test_password_reset_ACCOUNT_LOGIN_ON_PASSWORD_RESET(self): user = self._request_new_password() body = mail.outbox[0].body url = body[body.find("/accounts/password/reset/") :].split()[0] resp = self.client.get(url) # Follow the redirect the actual password reset page with the key # hidden. resp = self.client.post( resp.url, {"password1": "newpass123", "password2": "newpass123"} ) self.assertTrue(user.is_authenticated) # EmailVerificationMethod.MANDATORY sends us to the confirm-email page self.assertRedirects(resp, "/accounts/confirm-email/") def _create_user(self, username="john", password="doe", **kwargs): user = get_user_model().objects.create( username=username, is_active=True, **kwargs ) if password: user.set_password(password) else: user.set_unusable_password() user.save() return user def _create_user_and_login(self, usable_password=True): password = "doe" if usable_password else False user = self._create_user(password=password) self.client.force_login(user) return user def test_password_reset_flow(client, user, mailoutbox, settings): """ Tests the password reset flow: requesting a new password, receiving the reset link via email and finally resetting the password to a new value. """ settings.ACCOUNT_EMAIL_NOTIFICATIONS = True # Request new password client.post( reverse("account_reset_password"), data={"email": user.email}, ) assert len(mail.outbox) == 1 assert mailoutbox[0].to == [user.email] body = mailoutbox[0].body assert body.find("http://") > 0 # Extract URL for `password_reset_from_key` view and access it url = body[body.find("/accounts/password/reset/") :].split()[0] resp = client.get(url) # Follow the redirect the actual password reset page with the key # hidden. url = resp.url resp = client.get(url) assertTemplateUsed( resp, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION, ) assert "token_fail" not in resp.context_data # Reset the password resp = client.post(url, {"password1": "newpass123", "password2": "newpass123"}) assertRedirects(resp, reverse("account_reset_password_from_key_done")) assert "Your password has been reset" in mailoutbox[-1].body # Check the new password is in effect user = get_user_model().objects.get(pk=user.pk) assert user.check_password("newpass123") # Trying to reset the password against the same URL (or any other # invalid/obsolete URL) returns a bad token response resp = client.post(url, {"password1": "newpass123", "password2": "newpass123"}) assertTemplateUsed( resp, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION, ) assert resp.context_data["token_fail"] # Same should happen when accessing the page directly response = client.get(url) assertTemplateUsed( response, "account/password_reset_from_key.%s" % app_settings.TEMPLATE_EXTENSION, ) assert response.context_data["token_fail"] # When in XHR views, it should respond with a 400 bad request # code, and the response body should contain the JSON-encoded # error from the adapter response = client.post( url, {"password1": "newpass123", "password2": "newpass123"}, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) assert response.status_code == 400 data = json.loads(response.content.decode("utf8")) assert "invalid" in data["form"]["errors"][0] @pytest.mark.parametrize( "next_url,expected_location", [(None, reverse_lazy("account_reset_password_from_key_done")), ("/foo", "/foo")], ) def test_reset_password_from_key_next_url( user, client, password_factory, next_url, expected_location, password_reset_url ): url = password_reset_url(user) query = "" if next_url: query = "?" + urlencode({"next": next_url}) resp = client.get(url + query) assert resp.status_code == 302 assert ( resp["location"] == reverse( "account_reset_password_from_key", kwargs={"uidb36": user_pk_to_url_str(user), "key": "set-password"}, ) + query ) password = password_factory() data = {"password1": password, "password2": password} if next_url: data["next"] = next_url resp = client.post(resp["location"], data) assert resp.status_code == 302 assert resp["location"] == expected_location django-allauth-65.0.2/allauth/account/tests/test_security.py000066400000000000000000000031061467545753200242300ustar00rootroot00000000000000from allauth.account.forms import ResetPasswordForm def test_user_email_unicode_collision(settings, rf, user_factory, mailoutbox): settings.ACCOUNT_PREVENT_ENUMERATION = False user_factory(username="mike123", email="mike@example.org") user_factory(username="mike456", email="mıke@example.org") data = {"email": "mıke@example.org"} form = ResetPasswordForm(data) assert form.is_valid() form.save(rf.get("/")) assert len(mailoutbox) == 1 assert mailoutbox[0].to == ["mıke@example.org"] def test_user_email_domain_unicode_collision(settings, rf, user_factory, mailoutbox): settings.ACCOUNT_PREVENT_ENUMERATION = False user_factory(username="mike123", email="mike@ixample.org") user_factory(username="mike456", email="mike@ıxample.org") data = {"email": "mike@ıxample.org"} form = ResetPasswordForm(data) assert form.is_valid() form.save(rf.get("/")) assert len(mailoutbox) == 1 assert mailoutbox[0].to == ["mike@ıxample.org"] def test_user_email_unicode_collision_nonexistent(settings, user_factory): settings.ACCOUNT_PREVENT_ENUMERATION = False user_factory(username="mike123", email="mike@example.org") data = {"email": "mıke@example.org"} form = ResetPasswordForm(data) assert not form.is_valid() def test_user_email_domain_unicode_collision_nonexistent(settings, user_factory): settings.ACCOUNT_PREVENT_ENUMERATION = False user_factory(username="mike123", email="mike@ixample.org") data = {"email": "mike@ıxample.org"} form = ResetPasswordForm(data) assert not form.is_valid() django-allauth-65.0.2/allauth/account/tests/test_signup.py000066400000000000000000000372041467545753200236740ustar00rootroot00000000000000from django import forms from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.contrib.messages.middleware import MessageMiddleware from django.contrib.sessions.middleware import SessionMiddleware from django.core import mail from django.test.client import Client, RequestFactory from django.test.utils import override_settings from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.forms import BaseSignupForm, SignupForm from allauth.account.models import EmailAddress from allauth.core import context from allauth.tests import TestCase from allauth.utils import get_username_max_length class CustomSignupFormTests(TestCase): @override_settings( ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE=True, ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE=True, ) def test_custom_form_field_order(self): expected_field_order = [ "email", "email2", "password1", "password2", "username", "last_name", "first_name", ] class TestSignupForm(forms.Form): first_name = forms.CharField(max_length=30) last_name = forms.CharField(max_length=30) field_order = expected_field_order class CustomSignupForm(SignupForm, TestSignupForm): # ACCOUNT_SIGNUP_FORM_CLASS is only abided by when the # BaseSignupForm definition is loaded the first time on Django # startup. @override_settings() has therefore no effect. pass form = CustomSignupForm() self.assertEqual(list(form.fields.keys()), expected_field_order) def test_user_class_attribute(self): from django.contrib.auth import get_user_model from django.db.models.query_utils import DeferredAttribute class CustomSignupForm(SignupForm): # ACCOUNT_SIGNUP_FORM_CLASS is only abided by when the # BaseSignupForm definition is loaded the first time on Django # startup. @override_settings() has therefore no effect. pass User = get_user_model() data = { "username": "username", "email": "user@example.com", "password1": "very-secret", "password2": "very-secret", } form = CustomSignupForm(data, email_required=True) assert isinstance(User.username, DeferredAttribute) form.is_valid() assert isinstance(User.username, DeferredAttribute) class BaseSignupFormTests(TestCase): @override_settings( ACCOUNT_USERNAME_REQUIRED=True, ACCOUNT_USERNAME_BLACKLIST=["username"] ) def test_username_in_blacklist(self): data = { "username": "username", "email": "user@example.com", } form = BaseSignupForm(data, email_required=True) self.assertFalse(form.is_valid()) @override_settings( ACCOUNT_USERNAME_REQUIRED=True, ACCOUNT_USERNAME_BLACKLIST=["username"] ) def test_username_not_in_blacklist(self): data = { "username": "theusername", "email": "user@example.com", } form = BaseSignupForm(data, email_required=True) self.assertTrue(form.is_valid()) @override_settings(ACCOUNT_USERNAME_REQUIRED=True) def test_username_maxlength(self): data = { "username": "username", "email": "user@example.com", } form = BaseSignupForm(data, email_required=True) max_length = get_username_max_length() field = form.fields["username"] self.assertEqual(field.max_length, max_length) widget = field.widget self.assertEqual(widget.attrs.get("maxlength"), str(max_length)) def test_signup_email_verification(settings, db): settings.ACCOUNT_USERNAME_REQUIRED = True settings.ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE = True data = { "username": "username", "email": "user@example.com", } form = BaseSignupForm(data, email_required=True) assert not form.is_valid() data = { "username": "username", "email": "user@example.com", "email2": "USER@example.COM", } form = BaseSignupForm(data, email_required=True) assert form.is_valid() data["email2"] = "anotheruser@example.com" form = BaseSignupForm(data, email_required=True) assert not form.is_valid() @override_settings( ACCOUNT_DEFAULT_HTTP_PROTOCOL="https", ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY, ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME, ACCOUNT_SIGNUP_FORM_CLASS=None, ACCOUNT_EMAIL_SUBJECT_PREFIX=None, LOGIN_REDIRECT_URL="/accounts/profile/", ACCOUNT_SIGNUP_REDIRECT_URL="/accounts/welcome/", ACCOUNT_ADAPTER="allauth.account.adapter.DefaultAccountAdapter", ACCOUNT_USERNAME_REQUIRED=True, ) class SignupTests(TestCase): def test_signup_same_email_verified_externally(self): user = self._test_signup_email_verified_externally( "john@example.com", "john@example.com" ) self.assertEqual(EmailAddress.objects.filter(user=user).count(), 1) EmailAddress.objects.get( verified=True, email="john@example.com", user=user, primary=True ) def test_signup_other_email_verified_externally(self): """ John is invited on john@example.org, but signs up via john@example.com. Email verification is by-passed, their home email address is used as a secondary. """ user = self._test_signup_email_verified_externally( "john@example.com", "john@example.org" ) self.assertEqual(EmailAddress.objects.filter(user=user).count(), 2) EmailAddress.objects.get( verified=False, email="john@example.com", user=user, primary=False ) EmailAddress.objects.get( verified=True, email="john@example.org", user=user, primary=True ) def _test_signup_email_verified_externally(self, signup_email, verified_email): username = "johndoe" request = RequestFactory().post( reverse("account_signup"), { "username": username, "email": signup_email, "password1": "johndoe", "password2": "johndoe", }, ) # Fake stash_verified_email SessionMiddleware(lambda request: None).process_request(request) MessageMiddleware(lambda request: None).process_request(request) request.user = AnonymousUser() request.session["account_verified_email"] = verified_email from allauth.account.views import signup with context.request_context(request): resp = signup(request) self.assertEqual(resp.status_code, 302) self.assertEqual( resp["location"], get_adapter().get_signup_redirect_url(request) ) self.assertEqual(len(mail.outbox), 0) return get_user_model().objects.get(username=username) @override_settings( ACCOUNT_USERNAME_REQUIRED=True, ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE=True, ) def test_signup_password_twice_form_error(self): resp = self.client.post( reverse("account_signup"), data={ "username": "johndoe", "email": "john@example.org", "password1": "johndoe", "password2": "janedoe", }, ) self.assertFormError( resp.context["form"], "password2", "You must type the same password each time.", ) @override_settings( ACCOUNT_USERNAME_REQUIRED=True, ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE=True ) def test_signup_email_twice(self): request = RequestFactory().post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.org", "email2": "john@example.org", "password1": "johndoe", "password2": "johndoe", }, ) SessionMiddleware(lambda request: None).process_request(request) MessageMiddleware(lambda request: None).process_request(request) request.user = AnonymousUser() from allauth.account.views import signup with context.request_context(request): signup(request) user = get_user_model().objects.get(username="johndoe") self.assertEqual(user.email, "john@example.org") @override_settings( AUTH_PASSWORD_VALIDATORS=[ { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", "OPTIONS": { "min_length": 9, }, } ] ) def test_django_password_validation(self): resp = self.client.post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.com", "password1": "johndoe", "password2": "johndoe", }, ) self.assertFormError(resp.context["form"], None, []) self.assertFormError( resp.context["form"], "password1", ["This password is too short. It must contain at least 9 characters."], ) def test_prevent_enumeration_with_mandatory_verification( settings, user_factory, email_factory ): settings.ACCOUNT_PREVENT_ENUMERATION = True settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.MANDATORY user = user_factory(username="john", email="john@example.org", password="doe") c = Client() resp = c.post( reverse("account_signup"), { "username": "johndoe", "email": email_factory(email=user.email, mixed_case=True), "password1": "johndoe", "password2": "johndoe", }, ) assert resp.status_code == 302 assert resp["location"] == reverse("account_email_verification_sent") assertTemplateUsed(resp, "account/email/account_already_exists_message.txt") assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt") assert EmailAddress.objects.filter(email="john@example.org").count() == 1 def test_prevent_enumeration_off(settings, user_factory, email_factory): settings.ACCOUNT_PREVENT_ENUMERATION = False settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.MANDATORY user = user_factory(username="john", email="john@example.org", password="doe") c = Client() resp = c.post( reverse("account_signup"), { "username": "johndoe", "email": email_factory(email=user.email, mixed_case=True), "password1": "johndoe", "password2": "johndoe", }, ) assert resp.status_code == 200 assert resp.context["form"].errors == { "email": ["A user is already registered with this email address."] } def test_prevent_enumeration_strictly(settings, user_factory, email_factory): settings.ACCOUNT_PREVENT_ENUMERATION = "strict" settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.NONE user = user_factory(username="john", email="john@example.org", password="doe") c = Client() resp = c.post( reverse("account_signup"), { "username": "johndoe", "email": email_factory(email=user.email, mixed_case=True), "password1": "johndoe", "password2": "johndoe", }, ) assert resp.status_code == 302 assert resp["location"] == settings.LOGIN_REDIRECT_URL assert EmailAddress.objects.filter(email="john@example.org").count() == 2 def test_prevent_enumeration_on(settings, user_factory, email_factory): settings.ACCOUNT_PREVENT_ENUMERATION = True settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.NONE user = user_factory(username="john", email="john@example.org", password="doe") c = Client() resp = c.post( reverse("account_signup"), { "username": "johndoe", "email": email_factory(email=user.email, mixed_case=True), "password1": "johndoe", "password2": "johndoe", }, ) assert resp.status_code == 200 assert resp.context["form"].errors == { "email": ["A user is already registered with this email address."] } @pytest.mark.django_db def test_get_initial_with_valid_email(): """Test that the email field is populated with a valid email.""" request = RequestFactory().get("/signup/?email=test@example.com") from allauth.account.views import signup SessionMiddleware(lambda request: None).process_request(request) request.user = AnonymousUser() with context.request_context(request): view = signup(request) assert view.context_data["view"].get_initial()["email"] == "test@example.com" def test_signup_user_model_no_email(settings, client, password_factory, db, mailoutbox): settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.MANDATORY settings.ACCOUNT_USER_MODEL_EMAIL_FIELD = None password = password_factory() email = "user@example.com" resp = client.post( reverse("account_signup"), { "email": email, "password1": password, "password2": password, }, ) assert resp.status_code == 302 email = EmailAddress.objects.get(email=email) assert email.primary assert not email.verified assert len(mailoutbox) == 1 def test_email_lower_case(db, settings): settings.ACCOUNT_AUTHENTICATION_METHOD = app_settings.AuthenticationMethod.EMAIL settings.ACCOUNT_EMAIL_VERIFICATION = app_settings.EmailVerificationMethod.NONE c = Client() resp = c.post( reverse("account_signup"), { "username": "johndoe", "email": "JoHn@DoE.oRg", "password1": "johndoe", "password2": "johndoe", }, ) assert resp.status_code == 302 assert EmailAddress.objects.filter(email="john@doe.org").count() == 1 def test_does_not_create_user_when_honeypot_filled_out(client, db, settings): settings.ACCOUNT_SIGNUP_FORM_HONEYPOT_FIELD = "phone_number" resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.com", "password1": "Password1@", "password2": "Password1@", "phone_number": "5551231234", }, ) assert not get_user_model().objects.all().exists() assert resp.status_code == 302 def test_create_user_when_honeypot_not_filled_out(client, db, settings): settings.ACCOUNT_SIGNUP_FORM_HONEYPOT_FIELD = "phone_number" resp = client.post( reverse("account_signup"), { "username": "johndoe", "email": "john@example.com", "password1": "Password1@", "password2": "Password1@", "phone_number": "", }, ) assert get_user_model().objects.filter(username="johndoe").count() == 1 assert resp.status_code == 302 django-allauth-65.0.2/allauth/account/tests/test_utils.py000066400000000000000000000126711467545753200235300ustar00rootroot00000000000000import uuid from unittest.mock import patch from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.messages.api import get_messages from django.contrib.messages.middleware import MessageMiddleware from django.contrib.sessions.middleware import SessionMiddleware from django.core import mail, validators from django.core.exceptions import ValidationError from django.template import Context, Template from django.test.client import RequestFactory from django.test.utils import override_settings from django.urls import reverse import allauth.app_settings from allauth.account.adapter import get_adapter from allauth.account.models import EmailAddress from allauth.account.utils import ( filter_users_by_username, url_str_to_user_pk, user_pk_to_url_str, user_username, ) from allauth.core import context from allauth.tests import TestCase from .test_models import UUIDUser test_username_validators = [ validators.RegexValidator(regex=r"^[a-c]+$", message="not abc") ] class UtilsTests(TestCase): def setUp(self): self.user_id = uuid.uuid4().hex def test_url_str_to_pk_identifies_UUID_as_stringlike(self): with patch("allauth.account.utils.get_user_model") as mocked_gum: mocked_gum.return_value = UUIDUser self.assertEqual(url_str_to_user_pk(self.user_id), uuid.UUID(self.user_id)) def test_pk_to_url_string_identifies_UUID_as_stringlike(self): with patch("allauth.account.utils.get_user_model") as mocked_gum: mocked_gum.return_value = UUIDUser user = UUIDUser(is_active=True, email="john@example.com", username="john") self.assertEqual(user_pk_to_url_str(user), user.pk.hex) @override_settings(ACCOUNT_PRESERVE_USERNAME_CASING=False) def test_username_lower_cased(self): user = get_user_model()() user_username(user, "CamelCase") self.assertEqual(user_username(user), "camelcase") # TODO: Actually test something filter_users_by_username("CamelCase", "FooBar") @override_settings(ACCOUNT_PRESERVE_USERNAME_CASING=True) def test_username_case_preserved(self): user = get_user_model()() user_username(user, "CamelCase") self.assertEqual(user_username(user), "CamelCase") # TODO: Actually test something filter_users_by_username("camelcase", "foobar") def test_user_display(self): user = get_user_model()(username="john
doe") expected_name = "john<br/>doe" templates = [ "{% load account %}{% user_display user %}", "{% load account %}{% user_display user as x %}{{ x }}", ] for template in templates: t = Template(template) content = t.render(Context({"user": user})) self.assertEqual(content, expected_name) def test_message_escaping(self): request = RequestFactory().get("/") SessionMiddleware(lambda request: None).process_request(request) MessageMiddleware(lambda request: None).process_request(request) user = get_user_model()() user_username(user, "'<8") context = {"user": user} get_adapter().add_message( request, messages.SUCCESS, "account/messages/logged_in.txt", context ) msgs = get_messages(request) actual_message = msgs._queued_messages[0].message assert user.username in actual_message, actual_message def test_email_escaping(self): site_name = "testserver" if allauth.app_settings.SITES_ENABLED: from django.contrib.sites.models import Site site = Site.objects.get_current() site.name = site_name = '' site.save() u = get_user_model().objects.create(username="test", email="user@example.com") request = RequestFactory().get("/") EmailAddress.objects.add_email(request, u, u.email, confirm=True) self.assertTrue(mail.outbox[0].subject[1:].startswith(site_name)) @override_settings( ACCOUNT_USERNAME_VALIDATORS="allauth.account.tests.test_utils.test_username_validators" ) def test_username_validator(self): get_adapter().clean_username("abc") self.assertRaises(ValidationError, lambda: get_adapter().clean_username("def")) @override_settings(ALLOWED_HOSTS=["allowed_host", "testserver"]) def test_is_safe_url_no_wildcard(self): with context.request_context(RequestFactory().get("/")): self.assertTrue(get_adapter().is_safe_url("http://allowed_host/")) self.assertFalse(get_adapter().is_safe_url("http://other_host/")) @override_settings(ALLOWED_HOSTS=["*"]) def test_is_safe_url_wildcard(self): with context.request_context(RequestFactory().get("/")): self.assertTrue(get_adapter().is_safe_url("http://foobar.com/")) self.assertTrue(get_adapter().is_safe_url("http://other_host/")) @override_settings(ALLOWED_HOSTS=["allowed_host", "testserver"]) def test_is_safe_url_relative_path(self): with context.request_context(RequestFactory().get("/")): self.assertTrue(get_adapter().is_safe_url("/foo/bar")) def test_redirect_noreversematch(auth_client): # We used to call `django.shortcuts.redirect()` as is, but that one throws a # `NoReverseMatch`, resulting in 500s. resp = auth_client.post(reverse("account_logout") + "?next=badurlname") assert resp["location"] == "/badurlname" django-allauth-65.0.2/allauth/account/urls.py000066400000000000000000000052671467545753200211570ustar00rootroot00000000000000from django.conf import settings from django.urls import path, re_path from allauth import app_settings as allauth_app_settings from allauth.account import app_settings from . import views urlpatterns = [ path("login/", views.login, name="account_login"), path("logout/", views.logout, name="account_logout"), path("inactive/", views.account_inactive, name="account_inactive"), ] if not allauth_app_settings.SOCIALACCOUNT_ONLY: urlpatterns.extend( [ path("signup/", views.signup, name="account_signup"), path( "reauthenticate/", views.reauthenticate, name="account_reauthenticate" ), # Email path("email/", views.email, name="account_email"), path( "confirm-email/", views.email_verification_sent, name="account_email_verification_sent", ), re_path( r"^confirm-email/(?P[-:\w]+)/$", views.confirm_email, name="account_confirm_email", ), path( "password/change/", views.password_change, name="account_change_password", ), path("password/set/", views.password_set, name="account_set_password"), # password reset path( "password/reset/", views.password_reset, name="account_reset_password" ), path( "password/reset/done/", views.password_reset_done, name="account_reset_password_done", ), re_path( r"^password/reset/key/(?P[0-9A-Za-z]+)-(?P.+)/$", views.password_reset_from_key, name="account_reset_password_from_key", ), path( "password/reset/key/done/", views.password_reset_from_key_done, name="account_reset_password_from_key_done", ), path( "login/code/confirm/", views.confirm_login_code, name="account_confirm_login_code", ), ] ) if getattr(settings, "MFA_PASSKEY_SIGNUP_ENABLED", False): urlpatterns.append( path( "signup/passkey/", views.signup_by_passkey, name="account_signup_by_passkey", ) ) if app_settings.LOGIN_BY_CODE_ENABLED: urlpatterns.extend( [ path( "login/code/", views.request_login_code, name="account_request_login_code", ), ] ) django-allauth-65.0.2/allauth/account/utils.py000066400000000000000000000314771467545753200213340ustar00rootroot00000000000000import unicodedata from collections import OrderedDict from typing import Optional from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model from django.core.exceptions import FieldDoesNotExist from django.db import models from django.db.models import Q from django.utils.encoding import force_str from django.utils.http import base36_to_int, int_to_base36 from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.internal import flows from allauth.account.models import Login from allauth.core.internal import httpkit from allauth.utils import ( get_request_param, import_callable, valid_email_or_none, ) def _unicode_ci_compare(s1, s2) -> bool: """ Perform case-insensitive comparison of two identifiers, using the recommended algorithm from Unicode Technical Report 36, section 2.11.2(B)(2). """ norm_s1 = unicodedata.normalize("NFKC", s1).casefold() norm_s2 = unicodedata.normalize("NFKC", s2).casefold() return norm_s1 == norm_s2 def get_next_redirect_url( request, redirect_field_name=REDIRECT_FIELD_NAME ) -> Optional[str]: """ Returns the next URL to redirect to, if it was explicitly passed via the request. """ redirect_to = get_request_param(request, redirect_field_name) if redirect_to and not get_adapter().is_safe_url(redirect_to): redirect_to = None return redirect_to def get_login_redirect_url( request, url=None, redirect_field_name=REDIRECT_FIELD_NAME, signup=False ) -> str: ret = url if url and callable(url): # In order to be able to pass url getters around that depend # on e.g. the authenticated state. ret = url() if not ret: ret = get_next_redirect_url(request, redirect_field_name=redirect_field_name) if not ret: if signup: ret = get_adapter().get_signup_redirect_url(request) else: ret = get_adapter().get_login_redirect_url(request) return ret _user_display_callable = None def default_user_display(user) -> str: ret = "" if app_settings.USER_MODEL_USERNAME_FIELD: ret = getattr(user, app_settings.USER_MODEL_USERNAME_FIELD) return ret or force_str(user) or user._meta.verbose_name def user_display(user) -> str: global _user_display_callable if not _user_display_callable: f = getattr(settings, "ACCOUNT_USER_DISPLAY", default_user_display) _user_display_callable = import_callable(f) return _user_display_callable(user) def user_field(user, field, *args, commit=False): """ Gets or sets (optional) user model fields. No-op if fields do not exist. """ if not field: return User = get_user_model() try: field_meta = User._meta.get_field(field) max_length = field_meta.max_length except FieldDoesNotExist: if not hasattr(user, field): return max_length = None if args: # Setter v = args[0] if v: v = v[0:max_length] setattr(user, field, v) if commit: user.save(update_fields=[field]) else: # Getter return getattr(user, field) def user_username(user, *args, commit=False): if args and not app_settings.PRESERVE_USERNAME_CASING and args[0]: args = [args[0].lower()] return user_field(user, app_settings.USER_MODEL_USERNAME_FIELD, *args) def user_email(user, *args, commit=False): if args and args[0]: args = [args[0].lower()] ret = user_field(user, app_settings.USER_MODEL_EMAIL_FIELD, *args, commit=commit) if ret: ret = ret.lower() return ret def has_verified_email(user, email=None) -> bool: from .models import EmailAddress emailaddress = None if email: ret = False try: emailaddress = EmailAddress.objects.get_for_user(user, email) ret = emailaddress.verified except EmailAddress.DoesNotExist: pass else: ret = EmailAddress.objects.filter(user=user, verified=True).exists() return ret def perform_login( request, user, email_verification=None, redirect_url=None, signal_kwargs=None, signup=False, email=None, ): login = Login( user=user, email_verification=email_verification, redirect_url=redirect_url, signal_kwargs=signal_kwargs, signup=signup, email=email, ) return flows.login.perform_login(request, login) def complete_signup(request, user, email_verification, success_url, signal_kwargs=None): return flows.signup.complete_signup( request, user=user, email_verification=email_verification, redirect_url=success_url, signal_kwargs=signal_kwargs, ) def cleanup_email_addresses(request, addresses): """ Takes a list of EmailAddress instances and cleans it up, making sure only valid ones remain, without multiple primaries etc. Order is important: e.g. if multiple primary email addresses exist, the first one encountered will be kept as primary. """ from .models import EmailAddress adapter = get_adapter() # Let's group by `email` e2a = OrderedDict() # maps email to EmailAddress primary_addresses = [] verified_addresses = [] primary_verified_addresses = [] for address in addresses: # Pick up only valid ones... email = valid_email_or_none(address.email) if not email: continue address.email = email # `valid_email_or_none` lower cases # ... and non-conflicting ones... if ( app_settings.UNIQUE_EMAIL and app_settings.PREVENT_ENUMERATION != "strict" and EmailAddress.objects.lookup([email]) ): # Email address already exists. continue if ( app_settings.UNIQUE_EMAIL and app_settings.PREVENT_ENUMERATION == "strict" and address.verified and EmailAddress.objects.is_verified(email) ): # Email address already exists, and is verified as well. continue a = e2a.get(email) if a: a.primary = a.primary or address.primary a.verified = a.verified or address.verified else: a = address a.verified = a.verified or adapter.is_email_verified(request, a.email) e2a[email] = a if a.primary: primary_addresses.append(a) if a.verified: primary_verified_addresses.append(a) if a.verified: verified_addresses.append(a) # Now that we got things sorted out, let's assign a primary if primary_verified_addresses: primary_address = primary_verified_addresses[0] elif verified_addresses: # Pick any verified as primary primary_address = verified_addresses[0] elif primary_addresses: # Okay, let's pick primary then, even if unverified primary_address = primary_addresses[0] elif e2a: # Pick the first primary_address = list(e2a.values())[0] else: # Empty primary_address = None # There can only be one primary for a in e2a.values(): a.primary = primary_address.email.lower() == a.email.lower() return list(e2a.values()), primary_address def setup_user_email(request, user, addresses): """ Creates proper EmailAddress for the user that was just signed up. Only sets up, doesn't do any other handling such as sending out email confirmation mails etc. """ from .models import EmailAddress assert not EmailAddress.objects.filter(user=user).exists() priority_addresses = [] # Is there a stashed email? adapter = get_adapter() stashed_email = adapter.unstash_verified_email(request) if stashed_email: priority_addresses.append( EmailAddress( user=user, email=stashed_email.lower(), primary=True, verified=True ) ) email = user_email(user) if email: priority_addresses.append( EmailAddress(user=user, email=email.lower(), primary=True, verified=False) ) addresses, primary = cleanup_email_addresses( request, priority_addresses + addresses ) for a in addresses: a.user = user a.save() EmailAddress.objects.fill_cache_for_user(user, addresses) if primary and (email or "").lower() != primary.email.lower(): user_email(user, primary.email) user.save() return primary def send_email_confirmation(request, user, signup=False, email=None) -> bool: return flows.email_verification.send_verification_email( request, user, signup=signup, email=email ) def sync_user_email_addresses(user): """ Keep user.email in sync with user.emailaddress_set. Under some circumstances the user.email may not have ended up as an EmailAddress record, e.g. in the case of manually created admin users. """ from .models import EmailAddress email = user_email(user) if email and not EmailAddress.objects.filter(user=user, email=email).exists(): # get_or_create() to gracefully handle races EmailAddress.objects.get_or_create( user=user, email=email, defaults={"primary": False, "verified": False} ) def filter_users_by_username(*username): if app_settings.PRESERVE_USERNAME_CASING: qlist = [ Q(**{app_settings.USER_MODEL_USERNAME_FIELD + "__iexact": u}) for u in username ] q = qlist[0] for q2 in qlist[1:]: q = q | q2 ret = get_user_model()._default_manager.filter(q) else: ret = get_user_model()._default_manager.filter( **{ app_settings.USER_MODEL_USERNAME_FIELD + "__in": [u.lower() for u in username] } ) return ret def filter_users_by_email( email: str, is_active: Optional[bool] = None, prefer_verified: bool = False ): """Return list of users by email address Typically one, at most just a few in length. First we look through EmailAddress table, than customisable User model table. Add results together avoiding SQL joins and deduplicate. `prefer_verified`: When looking up users by email, there can be cases where users with verified email addresses are preferable above users who did not verify their email address. The password reset is such a use case -- if there is a user with a verified email than that user should be returned, not one of the other users. """ from .models import EmailAddress User = get_user_model() email = email.lower() mails = list(EmailAddress.objects.filter(email=email).select_related("user")) is_verified = False if prefer_verified: verified_mails = list(filter(lambda e: e.verified, mails)) if verified_mails: mails = verified_mails is_verified = True users = [] for e in mails: if _unicode_ci_compare(e.email, email): users.append(e.user) if app_settings.USER_MODEL_EMAIL_FIELD and not is_verified: q_dict = {app_settings.USER_MODEL_EMAIL_FIELD: email} user_qs = User.objects.filter(**q_dict) for user in user_qs.iterator(): user_email = getattr(user, app_settings.USER_MODEL_EMAIL_FIELD) if _unicode_ci_compare(user_email, email): users.append(user) if is_active is not None: users = [u for u in set(users) if u.is_active == is_active] return list(set(users)) def passthrough_next_redirect_url(request, url, redirect_field_name): next_url = get_next_redirect_url(request, redirect_field_name) if next_url: url = httpkit.add_query_params(url, {redirect_field_name: next_url}) return url def user_pk_to_url_str(user) -> str: """ This should return a string. """ User = get_user_model() pk_field_class = type(User._meta.pk) if issubclass(pk_field_class, models.UUIDField): if isinstance(user.pk, str): return user.pk return user.pk.hex elif issubclass(pk_field_class, models.IntegerField): return int_to_base36(int(user.pk)) return str(user.pk) def url_str_to_user_pk(pk_str): User = get_user_model() remote_field = getattr(User._meta.pk, "remote_field", None) if remote_field and getattr(remote_field, "to", None): pk_field = User._meta.pk.remote_field.to._meta.pk else: pk_field = User._meta.pk pk_field_class = type(pk_field) if issubclass(pk_field_class, models.IntegerField): pk = base36_to_int(pk_str) # always call to_python() -- because there are fields like HashidField # that derive from IntegerField. pk = pk_field.to_python(pk) else: pk = pk_field.to_python(pk_str) return pk django-allauth-65.0.2/allauth/account/views.py000066400000000000000000001051311467545753200213160ustar00rootroot00000000000000from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import PermissionDenied from django.core.validators import validate_email from django.forms import ValidationError from django.http import Http404, HttpResponse, HttpResponseRedirect from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator from django.views.decorators.cache import never_cache from django.views.decorators.debug import sensitive_post_parameters from django.views.generic.base import TemplateView from django.views.generic.edit import FormView from allauth import app_settings as allauth_app_settings from allauth.account import app_settings from allauth.account.adapter import get_adapter from allauth.account.forms import ( AddEmailForm, ChangePasswordForm, ConfirmEmailVerificationCodeForm, ConfirmLoginCodeForm, LoginForm, ReauthenticateForm, RequestLoginCodeForm, ResetPasswordForm, ResetPasswordKeyForm, SetPasswordForm, SignupForm, UserTokenForm, ) from allauth.account.internal import flows from allauth.account.internal.decorators import ( login_not_required, login_stage_required, ) from allauth.account.mixins import ( AjaxCapableProcessFormViewMixin, CloseableSignupMixin, LogoutFunctionalityMixin, NextRedirectMixin, RedirectAuthenticatedUserMixin, _ajax_response, ) from allauth.account.models import ( EmailAddress, EmailConfirmation, get_emailconfirmation_model, ) from allauth.account.stages import ( EmailVerificationStage, LoginByCodeStage, LoginStageController, ) from allauth.account.utils import ( perform_login, send_email_confirmation, sync_user_email_addresses, user_display, ) from allauth.core import ratelimit from allauth.core.exceptions import ImmediateHttpResponse from allauth.core.internal.httpkit import redirect from allauth.decorators import rate_limit from allauth.utils import get_form_class INTERNAL_RESET_SESSION_KEY = "_password_reset_key" sensitive_post_parameters_m = method_decorator( sensitive_post_parameters("oldpassword", "password", "password1", "password2") ) class LoginView( NextRedirectMixin, RedirectAuthenticatedUserMixin, AjaxCapableProcessFormViewMixin, FormView, ): form_class = LoginForm template_name = "account/login." + app_settings.TEMPLATE_EXTENSION success_url = None @method_decorator(rate_limit(action="login")) @method_decorator(login_not_required) @sensitive_post_parameters_m @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): if allauth_app_settings.SOCIALACCOUNT_ONLY and request.method != "GET": raise PermissionDenied() return super().dispatch(request, *args, **kwargs) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["request"] = self.request return kwargs def get_form_class(self): return get_form_class(app_settings.FORMS, "login", self.form_class) def form_valid(self, form): redirect_url = self.get_success_url() try: return form.login(self.request, redirect_url=redirect_url) except ImmediateHttpResponse as e: return e.response def get_context_data(self, **kwargs): passkey_login_enabled = False if allauth_app_settings.MFA_ENABLED: from allauth.mfa import app_settings as mfa_settings passkey_login_enabled = mfa_settings.PASSKEY_LOGIN_ENABLED ret = super().get_context_data(**kwargs) signup_url = None if not allauth_app_settings.SOCIALACCOUNT_ONLY: signup_url = self.passthrough_next_url(reverse("account_signup")) site = get_current_site(self.request) ret.update( { "signup_url": signup_url, "site": site, "SOCIALACCOUNT_ENABLED": allauth_app_settings.SOCIALACCOUNT_ENABLED, "SOCIALACCOUNT_ONLY": allauth_app_settings.SOCIALACCOUNT_ONLY, "LOGIN_BY_CODE_ENABLED": app_settings.LOGIN_BY_CODE_ENABLED, "PASSKEY_LOGIN_ENABLED": passkey_login_enabled, } ) if app_settings.LOGIN_BY_CODE_ENABLED: request_login_code_url = self.passthrough_next_url( reverse("account_request_login_code") ) ret["request_login_code_url"] = request_login_code_url return ret login = LoginView.as_view() class SignupView( RedirectAuthenticatedUserMixin, CloseableSignupMixin, NextRedirectMixin, AjaxCapableProcessFormViewMixin, FormView, ): template_name = "account/signup." + app_settings.TEMPLATE_EXTENSION form_class = SignupForm @method_decorator(rate_limit(action="signup")) @method_decorator(login_not_required) @sensitive_post_parameters_m @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def get_form_class(self): return get_form_class(app_settings.FORMS, "signup", self.form_class) def form_valid(self, form): self.user, resp = form.try_save(self.request) if resp: return resp try: redirect_url = self.get_success_url() return flows.signup.complete_signup( self.request, user=self.user, redirect_url=redirect_url, by_passkey=form.by_passkey, ) except ImmediateHttpResponse as e: return e.response def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) passkey_signup_enabled = False if allauth_app_settings.MFA_ENABLED: from allauth.mfa import app_settings as mfa_settings passkey_signup_enabled = mfa_settings.PASSKEY_SIGNUP_ENABLED form = ret["form"] email = self.request.session.get("account_verified_email") if email: email_keys = ["email"] if app_settings.SIGNUP_EMAIL_ENTER_TWICE: email_keys.append("email2") for email_key in email_keys: form.fields[email_key].initial = email login_url = self.passthrough_next_url(reverse("account_login")) signup_url = self.passthrough_next_url(reverse("account_signup")) signup_by_passkey_url = None if passkey_signup_enabled: signup_by_passkey_url = self.passthrough_next_url( reverse("account_signup_by_passkey") ) site = get_current_site(self.request) ret.update( { "login_url": login_url, "signup_url": signup_url, "signup_by_passkey_url": signup_by_passkey_url, "site": site, "SOCIALACCOUNT_ENABLED": allauth_app_settings.SOCIALACCOUNT_ENABLED, "SOCIALACCOUNT_ONLY": allauth_app_settings.SOCIALACCOUNT_ONLY, "PASSKEY_SIGNUP_ENABLED": passkey_signup_enabled, } ) return ret def get_initial(self): initial = super().get_initial() email = self.request.GET.get("email") if email: try: validate_email(email) except ValidationError: return initial initial["email"] = email if app_settings.SIGNUP_EMAIL_ENTER_TWICE: initial["email2"] = email return initial signup = SignupView.as_view() class SignupByPasskeyView(SignupView): template_name = "account/signup_by_passkey." + app_settings.TEMPLATE_EXTENSION def get_form_kwargs(self): ret = super().get_form_kwargs() ret["by_passkey"] = True return ret signup_by_passkey = SignupByPasskeyView.as_view() @method_decorator(login_not_required, name="dispatch") class ConfirmEmailView(NextRedirectMixin, LogoutFunctionalityMixin, TemplateView): template_name = "account/email_confirm." + app_settings.TEMPLATE_EXTENSION def get(self, *args, **kwargs): try: self.object = self.get_object() self.logout_other_user(self.object) if app_settings.CONFIRM_EMAIL_ON_GET: return self.post(*args, **kwargs) except Http404: self.object = None ctx = self.get_context_data() if not self.object and get_adapter().is_ajax(self.request): resp = HttpResponse() resp.status_code = 400 else: resp = self.render_to_response(ctx) return _ajax_response(self.request, resp, data=self.get_ajax_data()) def logout_other_user(self, confirmation): """ In the event someone clicks on an email confirmation link for one account while logged into another account, logout of the currently logged in account. """ if ( self.request.user.is_authenticated and self.request.user.pk != confirmation.email_address.user_id ): self.logout() def post(self, *args, **kwargs): self.object = verification = self.get_object() email_address, response = flows.email_verification.verify_email_and_resume( self.request, verification ) if response: return response if not email_address: return self.respond(False) self.logout_other_user(self.object) return self.respond(True) def respond(self, success): redirect_url = self.get_redirect_url() if not redirect_url: ctx = self.get_context_data() return self.render_to_response(ctx) return redirect(redirect_url) def get_object(self, queryset=None): key = self.kwargs["key"] model = get_emailconfirmation_model() emailconfirmation = model.from_key(key) if not emailconfirmation: raise Http404() return emailconfirmation def get_queryset(self): qs = EmailConfirmation.objects.all_valid() qs = qs.select_related("email_address__user") return qs def get_ajax_data(self): ret = { "can_confirm": bool(self.object), } if self.object: ret["email"] = self.object.email_address.email ret["user"] = {"display": user_display(self.object.email_address.user)} return ret def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) site = get_current_site(self.request) ctx.update( { "site": site, "confirmation": self.object, "can_confirm": self.object and self.object.email_address.can_set_verified(), } ) if self.object: ctx["email"] = self.object.email_address.email return ctx def get_redirect_url(self): url = self.get_next_url() if not url: url = get_adapter(self.request).get_email_verification_redirect_url( self.object.email_address, ) return url confirm_email = ConfirmEmailView.as_view() @method_decorator(login_required, name="dispatch") @method_decorator(rate_limit(action="manage_email"), name="dispatch") class EmailView(AjaxCapableProcessFormViewMixin, FormView): template_name = ( "account/email_change." if app_settings.CHANGE_EMAIL else "account/email." ) + app_settings.TEMPLATE_EXTENSION form_class = AddEmailForm success_url = reverse_lazy("account_email") def get_form_class(self): return get_form_class(app_settings.FORMS, "add_email", self.form_class) def dispatch(self, request, *args, **kwargs): self._did_send_verification_email = False sync_user_email_addresses(request.user) return super().dispatch(request, *args, **kwargs) def get_form_kwargs(self): kwargs = super(EmailView, self).get_form_kwargs() kwargs["user"] = self.request.user return kwargs def form_valid(self, form): flows.manage_email.add_email(self.request, form) self._did_send_verification_email = True return super().form_valid(form) def post(self, request, *args, **kwargs): res = None if "action_add" in request.POST: res = super().post(request, *args, **kwargs) elif request.POST.get("email"): if "action_send" in request.POST: res = self._action_send(request) elif "action_remove" in request.POST: res = self._action_remove(request) elif "action_primary" in request.POST: res = self._action_primary(request) res = res or HttpResponseRedirect(self.get_success_url()) # Given that we bypassed AjaxCapableProcessFormViewMixin, # we'll have to call invoke it manually... res = _ajax_response(request, res, data=self._get_ajax_data_if()) else: # No email address selected res = HttpResponseRedirect(self.success_url) res = _ajax_response(request, res, data=self._get_ajax_data_if()) return res def _get_email_address(self, request): email = request.POST["email"] try: validate_email(email) except ValidationError: return None try: return EmailAddress.objects.get_for_user(user=request.user, email=email) except EmailAddress.DoesNotExist: pass def _action_send(self, request, *args, **kwargs): email_address = self._get_email_address(request) if email_address: send_email_confirmation( self.request, request.user, email=email_address.email ) self._did_send_verification_email = True if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: return HttpResponseRedirect(reverse("account_email_verification_sent")) def _action_remove(self, request, *args, **kwargs): email_address = self._get_email_address(request) if email_address: if flows.manage_email.delete_email(request, email_address): return HttpResponseRedirect(self.get_success_url()) def _action_primary(self, request, *args, **kwargs): email_address = self._get_email_address(request) if email_address: if flows.manage_email.mark_as_primary(request, email_address): return HttpResponseRedirect(self.get_success_url()) def get_context_data(self, **kwargs): ret = super(EmailView, self).get_context_data(**kwargs) emails = list( EmailAddress.objects.filter(user=self.request.user).order_by("email") ) ret.update( { "emailaddresses": emails, "emailaddress_radios": [ { "id": f"email_radio_{i}", "checked": email.primary or len(emails) == 1, "emailaddress": email, } for i, email in enumerate(emails) ], "add_email_form": ret.get("form"), "can_add_email": EmailAddress.objects.can_add_email(self.request.user), } ) if app_settings.CHANGE_EMAIL: ret.update( { "new_emailaddress": EmailAddress.objects.get_new(self.request.user), "current_emailaddress": EmailAddress.objects.get_verified( self.request.user ), } ) return ret def get_ajax_data(self): data = [] for emailaddress in self.request.user.emailaddress_set.all().order_by("pk"): data.append( { "id": emailaddress.pk, "email": emailaddress.email, "verified": emailaddress.verified, "primary": emailaddress.primary, } ) return data def get_success_url(self): if ( self._did_send_verification_email and app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED ): return reverse("account_email_verification_sent") return self.success_url email = EmailView.as_view() @method_decorator(login_required, name="dispatch") @method_decorator(rate_limit(action="change_password"), name="dispatch") class PasswordChangeView(AjaxCapableProcessFormViewMixin, NextRedirectMixin, FormView): template_name = "account/password_change." + app_settings.TEMPLATE_EXTENSION form_class = ChangePasswordForm def get_form_class(self): return get_form_class(app_settings.FORMS, "change_password", self.form_class) @sensitive_post_parameters_m def dispatch(self, request, *args, **kwargs): if not self.request.user.has_usable_password(): return HttpResponseRedirect(reverse("account_set_password")) return super().dispatch(request, *args, **kwargs) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["user"] = self.request.user return kwargs def get_default_success_url(self): return get_adapter().get_password_change_redirect_url(self.request) def form_valid(self, form): form.save() flows.password_change.finalize_password_change(self.request, form.user) return super().form_valid(form) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) # NOTE: For backwards compatibility ret["password_change_form"] = ret.get("form") # (end NOTE) return ret password_change = PasswordChangeView.as_view() @method_decorator(login_required, name="dispatch") @method_decorator( # NOTE: 'change_password' (iso 'set_') is intentional, there is no need to # differentiate between set and change. rate_limit(action="change_password"), name="dispatch", ) class PasswordSetView(AjaxCapableProcessFormViewMixin, NextRedirectMixin, FormView): template_name = "account/password_set." + app_settings.TEMPLATE_EXTENSION form_class = SetPasswordForm def get_form_class(self): return get_form_class(app_settings.FORMS, "set_password", self.form_class) @sensitive_post_parameters_m def dispatch(self, request, *args, **kwargs): if self.request.user.has_usable_password(): return HttpResponseRedirect(reverse("account_change_password")) return super().dispatch(request, *args, **kwargs) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["user"] = self.request.user return kwargs def get_default_success_url(self): return get_adapter().get_password_change_redirect_url(self.request) def form_valid(self, form): form.save() flows.password_change.finalize_password_set(self.request, form.user) return super().form_valid(form) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) # NOTE: For backwards compatibility ret["password_set_form"] = ret.get("form") # (end NOTE) return ret password_set = PasswordSetView.as_view() @method_decorator(login_not_required, name="dispatch") class PasswordResetView(NextRedirectMixin, AjaxCapableProcessFormViewMixin, FormView): template_name = "account/password_reset." + app_settings.TEMPLATE_EXTENSION form_class = ResetPasswordForm success_url = reverse_lazy("account_reset_password_done") def get_form_class(self): return get_form_class(app_settings.FORMS, "reset_password", self.form_class) def form_valid(self, form): r429 = ratelimit.consume_or_429( self.request, action="reset_password", key=form.cleaned_data["email"].lower(), ) if r429: return r429 form.save(self.request) return super().form_valid(form) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) login_url = self.passthrough_next_url(reverse("account_login")) # NOTE: For backwards compatibility ret["password_reset_form"] = ret.get("form") # (end NOTE) ret.update({"login_url": login_url}) return ret password_reset = PasswordResetView.as_view() class PasswordResetDoneView(TemplateView): template_name = "account/password_reset_done." + app_settings.TEMPLATE_EXTENSION password_reset_done = PasswordResetDoneView.as_view() @method_decorator(rate_limit(action="reset_password_from_key"), name="dispatch") @method_decorator(login_not_required, name="dispatch") class PasswordResetFromKeyView( AjaxCapableProcessFormViewMixin, NextRedirectMixin, LogoutFunctionalityMixin, FormView, ): template_name = "account/password_reset_from_key." + app_settings.TEMPLATE_EXTENSION form_class = ResetPasswordKeyForm success_url = reverse_lazy("account_reset_password_from_key_done") reset_url_key = "set-password" def get_form_class(self): return get_form_class( app_settings.FORMS, "reset_password_from_key", self.form_class ) def dispatch(self, request, uidb36, key, **kwargs): self.request = request self.key = key user_token_form_class = get_form_class( app_settings.FORMS, "user_token", UserTokenForm ) is_ajax = get_adapter().is_ajax(request) if self.key == self.reset_url_key or is_ajax: if not is_ajax: self.key = self.request.session.get(INTERNAL_RESET_SESSION_KEY, "") # (Ab)using forms here to be able to handle errors in XHR #890 token_form = user_token_form_class(data={"uidb36": uidb36, "key": self.key}) if token_form.is_valid(): self.reset_user = token_form.reset_user # In the event someone clicks on a password reset link # for one account while logged into another account, # logout of the currently logged in account. if ( self.request.user.is_authenticated and self.request.user.pk != self.reset_user.pk ): self.logout() self.request.session[INTERNAL_RESET_SESSION_KEY] = self.key return super().dispatch(request, uidb36, self.key, **kwargs) else: token_form = user_token_form_class(data={"uidb36": uidb36, "key": self.key}) if token_form.is_valid(): # Store the key in the session and redirect to the # password reset form at a URL without the key. That # avoids the possibility of leaking the key in the # HTTP Referer header. self.request.session[INTERNAL_RESET_SESSION_KEY] = self.key redirect_url = self.passthrough_next_url( self.request.path.replace(self.key, self.reset_url_key) ) return redirect(redirect_url) self.reset_user = None response = self.render_to_response(self.get_context_data(token_fail=True)) return _ajax_response(self.request, response, form=token_form) def get_context_data(self, **kwargs): ret = super(PasswordResetFromKeyView, self).get_context_data(**kwargs) ret["action_url"] = reverse( "account_reset_password_from_key", kwargs={ "uidb36": self.kwargs["uidb36"], "key": self.kwargs["key"], }, ) return ret def get_form_kwargs(self): kwargs = super(PasswordResetFromKeyView, self).get_form_kwargs() kwargs["user"] = self.reset_user kwargs["temp_key"] = self.key return kwargs def form_valid(self, form): form.save() flows.password_reset.finalize_password_reset(self.request, self.reset_user) if app_settings.LOGIN_ON_PASSWORD_RESET: return perform_login( self.request, self.reset_user, ) return super(PasswordResetFromKeyView, self).form_valid(form) password_reset_from_key = PasswordResetFromKeyView.as_view() @method_decorator(login_not_required, name="dispatch") class PasswordResetFromKeyDoneView(TemplateView): template_name = ( "account/password_reset_from_key_done." + app_settings.TEMPLATE_EXTENSION ) password_reset_from_key_done = PasswordResetFromKeyDoneView.as_view() class LogoutView(NextRedirectMixin, LogoutFunctionalityMixin, TemplateView): template_name = "account/logout." + app_settings.TEMPLATE_EXTENSION def get(self, *args, **kwargs): if app_settings.LOGOUT_ON_GET: return self.post(*args, **kwargs) if not self.request.user.is_authenticated: response = redirect(self.get_redirect_url()) return _ajax_response(self.request, response) ctx = self.get_context_data() response = self.render_to_response(ctx) return _ajax_response(self.request, response) def post(self, *args, **kwargs): url = self.get_redirect_url() self.logout() response = redirect(url) return _ajax_response(self.request, response) def get_redirect_url(self): return self.get_next_url() or get_adapter(self.request).get_logout_redirect_url( self.request ) logout = LogoutView.as_view() @method_decorator(login_not_required, name="dispatch") class AccountInactiveView(TemplateView): template_name = "account/account_inactive." + app_settings.TEMPLATE_EXTENSION account_inactive = AccountInactiveView.as_view() @method_decorator(login_not_required, name="dispatch") class EmailVerificationSentView(TemplateView): template_name = "account/verification_sent." + app_settings.TEMPLATE_EXTENSION class ConfirmEmailVerificationCodeView(FormView): template_name = ( "account/confirm_email_verification_code." + app_settings.TEMPLATE_EXTENSION ) form_class = ConfirmEmailVerificationCodeForm def dispatch(self, request, *args, **kwargs): self.stage = LoginStageController.enter(request, EmailVerificationStage.key) self.verification, self.pending_verification = ( flows.email_verification_by_code.get_pending_verification( request, peek=True ) ) # preventing enumeration? verification_is_fake = ( self.pending_verification and "code" not in self.pending_verification ) # Can we at all continue? if ( # No verification pending? ( not self.pending_verification ) # Anonymous, yet no stage (or fake verifcation)? or ( request.user.is_anonymous and not self.stage and not verification_is_fake ) ): return HttpResponseRedirect( reverse( "account_login" if request.user.is_anonymous else "account_email" ) ) return super().dispatch(request, *args, **kwargs) def get_form_class(self): return get_form_class( app_settings.FORMS, "confirm_email_verification_code", self.form_class ) def get_form_kwargs(self): ret = super().get_form_kwargs() ret["code"] = self.verification.key if self.verification else "" return ret def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) ret["email"] = self.pending_verification["email"] ret["cancel_url"] = None if self.stage else reverse("account_email") return ret def form_valid(self, form): email_address = self.verification.confirm(self.request) if self.stage: if not email_address: return self.stage.abort() return self.stage.exit() return HttpResponseRedirect(reverse("account_email")) def form_invalid(self, form): attempts_left = flows.email_verification_by_code.record_invalid_attempt( self.request, self.pending_verification ) if attempts_left: return super().form_invalid(form) adapter = get_adapter(self.request) adapter.add_message( self.request, messages.ERROR, message=adapter.error_messages["too_many_login_attempts"], ) return HttpResponseRedirect(reverse("account_login")) @method_decorator(login_not_required, name="dispatch") def email_verification_sent(request): if app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: return ConfirmEmailVerificationCodeView.as_view()(request) else: return EmailVerificationSentView.as_view()(request) class BaseReauthenticateView(NextRedirectMixin, FormView): def dispatch(self, request, *args, **kwargs): resp = self._check_reauthentication_method_available(request) if resp: return resp resp = self._check_ratelimit(request) if resp: return resp return super().dispatch(request, *args, **kwargs) def _check_ratelimit(self, request): return ratelimit.consume_or_429( self.request, action="reauthenticate", user=self.request.user, ) def _check_reauthentication_method_available(self, request): methods = get_adapter().get_reauthentication_methods(self.request.user) if any([m["url"] == request.path for m in methods]): # Method is available return None if not methods: # Reauthentication not available raise PermissionDenied("Reauthentication not available") url = self.passthrough_next_url(methods[0]["url"]) return HttpResponseRedirect(url) def get_default_success_url(self): url = get_adapter(self.request).get_login_redirect_url(self.request) return url def form_valid(self, form): response = flows.reauthentication.resume_request(self.request) if response: return response return super().form_valid(form) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) ret.update( { "reauthentication_alternatives": self.get_reauthentication_alternatives(), } ) return ret def get_reauthentication_alternatives(self): methods = get_adapter().get_reauthentication_methods(self.request.user) alts = [] for method in methods: alt = dict(method) if self.request.path == alt["url"]: continue alt["url"] = self.passthrough_next_url(alt["url"]) alts.append(alt) alts = sorted(alts, key=lambda alt: alt["description"]) return alts @method_decorator(login_required, name="dispatch") class ReauthenticateView(BaseReauthenticateView): form_class = ReauthenticateForm template_name = "account/reauthenticate." + app_settings.TEMPLATE_EXTENSION def get_form_class(self): return get_form_class(app_settings.FORMS, "reauthenticate", self.form_class) def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request.user return ret def form_valid(self, form): flows.reauthentication.reauthenticate_by_password(self.request) return super().form_valid(form) reauthenticate = ReauthenticateView.as_view() class RequestLoginCodeView(RedirectAuthenticatedUserMixin, NextRedirectMixin, FormView): form_class = RequestLoginCodeForm template_name = "account/request_login_code." + app_settings.TEMPLATE_EXTENSION def get_form_class(self): return get_form_class(app_settings.FORMS, "request_login_code", self.form_class) def form_valid(self, form): flows.login_by_code.request_login_code(self.request, form.cleaned_data["email"]) return super().form_valid(form) def get_success_url(self): if self.request.user.is_authenticated: return None url = reverse_lazy("account_confirm_login_code") url = self.passthrough_next_url(reverse("account_confirm_login_code")) return url def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) site = get_current_site(self.request) ret.update({"site": site}) return ret request_login_code = RequestLoginCodeView.as_view() @method_decorator( login_stage_required( stage=LoginByCodeStage.key, redirect_urlname="account_request_login_code" ), name="dispatch", ) class ConfirmLoginCodeView(NextRedirectMixin, FormView): form_class = ConfirmLoginCodeForm template_name = "account/confirm_login_code." + app_settings.TEMPLATE_EXTENSION @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): self.stage = request._login_stage self.user, self.pending_login = flows.login_by_code.get_pending_login( self.request, self.stage.login, peek=True ) if not self.pending_login: return HttpResponseRedirect(reverse("account_request_login_code")) return super().dispatch(request, *args, **kwargs) def get_form_class(self): return get_form_class(app_settings.FORMS, "confirm_login_code", self.form_class) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["code"] = self.pending_login.get("code", "") return kwargs def form_valid(self, form): redirect_url = self.get_next_url() return flows.login_by_code.perform_login_by_code( self.request, self.stage, redirect_url ) def form_invalid(self, form): attempts_left = flows.login_by_code.record_invalid_attempt( self.request, self.stage.login ) if attempts_left: return super().form_invalid(form) adapter = get_adapter(self.request) adapter.add_message( self.request, messages.ERROR, message=adapter.error_messages["too_many_login_attempts"], ) return HttpResponseRedirect( reverse( "account_request_login_code" if self.pending_login["initiated_by_user"] else "account_login" ) ) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) site = get_current_site(self.request) ret.update( { "site": site, "email": self.pending_login["email"], } ) return ret confirm_login_code = ConfirmLoginCodeView.as_view() django-allauth-65.0.2/allauth/app_settings.py000066400000000000000000000024541467545753200212310ustar00rootroot00000000000000from django.apps import apps class AppSettings: def __init__(self, prefix): self.prefix = prefix def _setting(self, name, dflt): from allauth.utils import get_setting return get_setting(self.prefix + name, dflt) @property def SITES_ENABLED(self): return apps.is_installed("django.contrib.sites") @property def SOCIALACCOUNT_ENABLED(self): return apps.is_installed("allauth.socialaccount") @property def SOCIALACCOUNT_ONLY(self) -> bool: from allauth.utils import get_setting return get_setting("SOCIALACCOUNT_ONLY", False) @property def MFA_ENABLED(self): return apps.is_installed("allauth.mfa") @property def USERSESSIONS_ENABLED(self): return apps.is_installed("allauth.usersessions") @property def HEADLESS_ENABLED(self): return apps.is_installed("allauth.headless") @property def HEADLESS_ONLY(self) -> bool: from allauth.utils import get_setting return get_setting("HEADLESS_ONLY", False) @property def DEFAULT_AUTO_FIELD(self): return self._setting("DEFAULT_AUTO_FIELD", None) _app_settings = AppSettings("ALLAUTH_") def __getattr__(name): # See https://peps.python.org/pep-0562/ return getattr(_app_settings, name) django-allauth-65.0.2/allauth/conftest.py000066400000000000000000000214171467545753200203560ustar00rootroot00000000000000import json import random import time import uuid from contextlib import contextmanager from unittest.mock import Mock, PropertyMock, patch from django.contrib.auth import get_user_model from django.contrib.messages.middleware import MessageMiddleware from django.contrib.sessions.middleware import SessionMiddleware import pytest from allauth.account.models import EmailAddress from allauth.account.utils import user_email, user_pk_to_url_str, user_username from allauth.core import context from allauth.socialaccount.internal import statekit from allauth.socialaccount.providers.base.constants import AuthProcess def pytest_collection_modifyitems(config, items): if config.getoption("--ds") == "tests.headless_only.settings": removed_items = [] for item in items: if not item.location[0].startswith("allauth/headless"): removed_items.append(item) for item in removed_items: items.remove(item) @pytest.fixture def user(user_factory): return user_factory() @pytest.fixture def auth_client(client, user): client.force_login(user) return client @pytest.fixture def password_factory(): def f(): return str(uuid.uuid4()) return f @pytest.fixture def user_password(password_factory): return password_factory() @pytest.fixture def email_verified(): return True @pytest.fixture def user_factory(email_factory, db, user_password, email_verified): def factory( email=None, username=None, commit=True, with_email=True, email_verified=email_verified, password=None, with_emailaddress=True, with_totp=False, ): if not username: username = uuid.uuid4().hex if not email and with_email: email = email_factory(username=username) User = get_user_model() user = User() if password == "!": user.password = password else: user.set_password(user_password if password is None else password) user_username(user, username) user_email(user, email or "") if commit: user.save() if email and with_emailaddress: EmailAddress.objects.create( user=user, email=email.lower(), verified=email_verified, primary=True, ) if with_totp: from allauth.mfa.totp.internal import auth auth.TOTP.activate(user, auth.generate_totp_secret()) return user return factory @pytest.fixture def email_factory(): def factory(username=None, email=None, mixed_case=False): if email is None: if not username: username = uuid.uuid4().hex email = f"{username}@{uuid.uuid4().hex}.org" if mixed_case: email = "".join([random.choice([c.upper(), c.lower()]) for c in email]) else: email = email.lower() return email return factory @pytest.fixture def reauthentication_bypass(): @contextmanager def f(): with patch( "allauth.account.internal.flows.reauthentication.did_recently_authenticate" ) as m: m.return_value = True yield return f @pytest.fixture def webauthn_authentication_bypass(): @contextmanager def f(authenticator): from fido2.utils import websafe_encode from allauth.mfa.adapter import get_adapter with patch( "allauth.mfa.webauthn.internal.auth.WebAuthn.authenticator_data", new_callable=PropertyMock, ) as ad_m: with patch("fido2.server.Fido2Server.authenticate_begin") as ab_m: ab_m.return_value = ({}, {"state": "dummy"}) with patch("fido2.server.Fido2Server.authenticate_complete") as ac_m: with patch( "allauth.mfa.webauthn.internal.auth.parse_authentication_response" ) as m: user_handle = ( get_adapter().get_public_key_credential_user_entity( authenticator.user )["id"] ) authenticator_data = Mock() authenticator_data.credential_data.credential_id = ( "credential_id" ) ad_m.return_value = authenticator_data m.return_value = Mock() binding = Mock() binding.credential_id = "credential_id" ac_m.return_value = binding yield json.dumps( {"response": {"userHandle": websafe_encode(user_handle)}} ) return f @pytest.fixture def webauthn_registration_bypass(): @contextmanager def f(user, passwordless): with patch("fido2.server.Fido2Server.register_complete") as rc_m: with patch( "allauth.mfa.webauthn.internal.auth.parse_registration_response" ) as m: m.return_value = Mock() class FakeAuthenticatorData(bytes): def is_user_verified(self): return passwordless binding = FakeAuthenticatorData(b"binding") rc_m.return_value = binding yield json.dumps( { "authenticatorAttachment": "cross-platform", "clientExtensionResults": {"credProps": {"rk": passwordless}}, "id": "123", "rawId": "456", "response": { "attestationObject": "ao", "clientDataJSON": "cdj", "transports": ["usb"], }, "type": "public-key", } ) return f @pytest.fixture(autouse=True) def clear_context_request(): context._request_var.set(None) @pytest.fixture def enable_cache(settings): from django.core.cache import cache settings.CACHES = { "default": { "BACKEND": "django.core.cache.backends.locmem.LocMemCache", } } cache.clear() yield @pytest.fixture def totp_validation_bypass(): @contextmanager def f(): with patch("allauth.mfa.totp.internal.auth.validate_totp_code") as m: m.return_value = True yield return f @pytest.fixture def provider_id(): return "unittest-server" @pytest.fixture def password_reset_key_generator(): def f(user): from allauth.account import app_settings token_generator = app_settings.PASSWORD_RESET_TOKEN_GENERATOR() uid = user_pk_to_url_str(user) temp_key = token_generator.make_token(user) key = f"{uid}-{temp_key}" return key return f @pytest.fixture def google_provider_settings(settings): gsettings = {"APPS": [{"client_id": "client_id", "secret": "secret"}]} settings.SOCIALACCOUNT_PROVIDERS = {"google": gsettings} return gsettings @pytest.fixture def user_with_totp(user): from allauth.mfa.totp.internal import auth auth.TOTP.activate(user, auth.generate_totp_secret()) return user @pytest.fixture def user_with_recovery_codes(user_with_totp): from allauth.mfa.recovery_codes.internal import auth auth.RecoveryCodes.activate(user_with_totp) return user_with_totp @pytest.fixture def passkey(user): from allauth.mfa.models import Authenticator authenticator = Authenticator.objects.create( user=user, type=Authenticator.Type.WEBAUTHN, data={ "name": "Test passkey", "passwordless": True, "credential": {}, }, ) return authenticator @pytest.fixture def user_with_passkey(user, passkey): return user @pytest.fixture def sociallogin_setup_state(): def setup(client, process=None, next_url=None, **kwargs): state_id = "123" session = client.session state = {"process": process or AuthProcess.LOGIN, **kwargs} if next_url: state["next"] = next_url states = {} states[state_id] = [state, time.time()] session[statekit.STATES_SESSION_KEY] = states session.save() return state_id return setup @pytest.fixture def request_factory(rf): class RequestFactory: def get(self, path): request = rf.get(path) SessionMiddleware(lambda request: None).process_request(request) MessageMiddleware(lambda request: None).process_request(request) return request return RequestFactory() django-allauth-65.0.2/allauth/core/000077500000000000000000000000001467545753200171025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/__init__.py000066400000000000000000000000001467545753200212010ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/context.py000066400000000000000000000006161467545753200211430ustar00rootroot00000000000000from contextlib import contextmanager from contextvars import ContextVar _request_var = ContextVar("request", default=None) def __getattr__(name): if name == "request": return _request_var.get() raise AttributeError(name) @contextmanager def request_context(request): token = _request_var.set(request) try: yield finally: _request_var.reset(token) django-allauth-65.0.2/allauth/core/exceptions.py000066400000000000000000000010101467545753200216250ustar00rootroot00000000000000class ImmediateHttpResponse(Exception): """ This exception is used to interrupt the flow of processing to immediately return a custom HttpResponse. """ def __init__(self, response): self.response = response class ReauthenticationRequired(Exception): """ The action could not be performed because the user needs to reauthenticate. """ pass class SignupClosedException(Exception): """ Throws when attemtping to signup while signup is closed. """ pass django-allauth-65.0.2/allauth/core/internal/000077500000000000000000000000001467545753200207165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/internal/__init__.py000066400000000000000000000000001467545753200230150ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/internal/adapter.py000066400000000000000000000007661467545753200227210ustar00rootroot00000000000000from django.core.exceptions import ValidationError from allauth.core import context class BaseAdapter: def __init__(self, request=None): # Explicitly passing `request` is deprecated, just use: # `allauth.core.context.request`. self.request = context.request def validation_error(self, code, *args): message = self.error_messages[code] if args: message = message % args exc = ValidationError(message, code=code) return exc django-allauth-65.0.2/allauth/core/internal/httpkit.py000066400000000000000000000062751467545753200227710ustar00rootroot00000000000000import json from urllib.parse import parse_qs, quote, urlencode, urlparse, urlunparse from django import shortcuts from django.core.exceptions import ImproperlyConfigured from django.http import ( HttpResponseRedirect, HttpResponseServerError, QueryDict, ) from django.urls import NoReverseMatch, reverse from allauth import app_settings as allauth_settings def serialize_request(request): return json.dumps( { "path": request.path, "path_info": request.path_info, "META": {k: v for k, v in request.META.items() if isinstance(v, str)}, "GET": request.GET.urlencode(), "POST": request.POST.urlencode(), "method": request.method, "scheme": request.scheme, } ) def deserialize_request(s, request): data = json.loads(s) request.GET = QueryDict(data["GET"]) request.POST = QueryDict(data["POST"]) request.META = data["META"] request.path = data["path"] request.path_info = data["path_info"] request.method = data["method"] request._get_scheme = lambda: data["scheme"] return request def redirect(to): try: return shortcuts.redirect(to) except NoReverseMatch: return shortcuts.redirect(f"/{to}") def add_query_params(url, params): parsed_url = urlparse(url) query_params = parse_qs(parsed_url.query) query_params.update(params) encoded_query = urlencode(query_params, doseq=True) new_url = urlunparse( ( parsed_url.scheme, parsed_url.netloc, parsed_url.path, parsed_url.params, encoded_query, parsed_url.fragment, ) ) return new_url def render_url(request, url_template, **kwargs): url = url_template for k, v in kwargs.items(): qi = url.find("?") ki = url.find("{" + k + "}") if ki < 0: raise ImproperlyConfigured(url_template) is_query_param = qi >= 0 and ki > qi if is_query_param: qv = urlencode({"k": v}).partition("k=")[2] else: qv = quote(v) url = url.replace("{" + k + "}", qv) p = urlparse(url) if not p.netloc: url = request.build_absolute_uri(url) return url def get_frontend_url(request, urlname, **kwargs): from allauth import app_settings as allauth_settings if allauth_settings.HEADLESS_ENABLED: from allauth.headless import app_settings as headless_settings url = headless_settings.FRONTEND_URLS.get(urlname) if allauth_settings.HEADLESS_ONLY and not url: raise ImproperlyConfigured(f"settings.HEADLESS_FRONTEND_URLS['{urlname}']") if url: return render_url(request, url, **kwargs) return None def headed_redirect_response(viewname): """ In some cases, we're redirecting to a non-headless view. In case of headless-only mode, that view clearly does not exist. """ try: return HttpResponseRedirect(reverse(viewname)) except NoReverseMatch: if allauth_settings.HEADLESS_ONLY: # The response we would be rendering here is not actually used. return HttpResponseServerError() raise django-allauth-65.0.2/allauth/core/internal/tests/000077500000000000000000000000001467545753200220605ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/internal/tests/__init__.py000066400000000000000000000000001467545753200241570ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/internal/tests/test_httpkit.py000066400000000000000000000025621467545753200251650ustar00rootroot00000000000000import json from django.http import HttpRequest import pytest from allauth.core.internal import httpkit @pytest.mark.parametrize( "url,params,expected_url", [ ("/", {"foo": "bar", "v": 1}, "/?foo=bar&v=1"), ( "https://fqdn/?replace=this", {"replace": "that"}, "https://fqdn/?replace=that", ), ], ) def test_add_query_params(url, params, expected_url): assert httpkit.add_query_params(url, params) == expected_url @pytest.mark.parametrize( "url_template,kwargs,expected_url", [ ("/foo", {}, "http://testserver/foo"), ("/foo?key={key}", {"key": " "}, "http://testserver/foo?key=+"), ("/foo/{key}", {"key": " "}, "http://testserver/foo/%20"), ("https://abs.org/foo?key={key}", {"key": " "}, "https://abs.org/foo?key=+"), ], ) def test_render_url(url_template, kwargs, expected_url, rf): request = rf.get("/") assert httpkit.render_url(request, url_template, **kwargs) == expected_url def test_deserialize_request(rf): request = rf.get("/") assert not request.is_secure() serialized = httpkit.serialize_request(request) assert not httpkit.deserialize_request(serialized, HttpRequest()).is_secure() data = json.loads(serialized) data["scheme"] = "https" assert httpkit.deserialize_request(json.dumps(data), HttpRequest()).is_secure() django-allauth-65.0.2/allauth/core/ratelimit.py000066400000000000000000000104701467545753200214500ustar00rootroot00000000000000import hashlib import time from collections import namedtuple from typing import Optional from django.conf import settings from django.core.cache import cache from django.core.exceptions import ImproperlyConfigured from django.http import HttpResponse from django.shortcuts import render from allauth import app_settings from allauth.utils import import_callable Rate = namedtuple("Rate", "amount duration per") def _parse_duration(duration): if len(duration) == 0: raise ValueError(duration) unit = duration[-1] value = duration[0:-1] unit_map = {"s": 1, "m": 60, "h": 3600, "d": 86400} if unit not in unit_map: raise ValueError("Invalid duration unit: %s" % unit) if len(value) == 0: value = 1 else: value = float(value) return value * unit_map[unit] def _parse_rate(rate): parts = rate.split("/") if len(parts) == 2: amount, duration = parts per = "ip" elif len(parts) == 3: amount, duration, per = parts else: raise ValueError(rate) amount = int(amount) duration = _parse_duration(duration) return Rate(amount, duration, per) def _parse_rates(rates): ret = [] if rates: rates = rates.strip() if rates: parts = rates.split(",") for part in parts: ret.append(_parse_rate(part.strip())) return ret def _cache_key(request, *, action, rate, key=None, user=None): from allauth.account.adapter import get_adapter if rate.per == "ip": source = ("ip", get_adapter().get_client_ip(request)) elif rate.per == "user": if user is None: if not request.user.is_authenticated: raise ImproperlyConfigured( "ratelimit configured per user but used anonymously" ) user = request.user source = ("user", str(user.pk)) elif rate.per == "key": if key is None: raise ImproperlyConfigured( "ratelimit configured per key but no key specified" ) key_hash = hashlib.sha256(key.encode("utf8")).hexdigest() source = (key_hash,) else: raise ValueError(rate.per) keys = ["allauth", "rl", action, *source] return ":".join(keys) def clear(request, *, action, key=None, user=None): from allauth.account import app_settings rates = _parse_rates(app_settings.RATE_LIMITS.get(action)) for rate in rates: cache_key = _cache_key(request, action=action, rate=rate, key=key, user=user) cache.delete(cache_key) def consume(request, *, action, key=None, user=None, dry_run: bool = False): from allauth.account import app_settings if not request or request.method == "GET": return True rates = _parse_rates(app_settings.RATE_LIMITS.get(action)) if not rates: return True allowed = True for rate in rates: if not _consume_rate( request, action=action, rate=rate, key=key, user=user, dry_run=dry_run ): allowed = False return allowed def _consume_rate(request, *, action, rate, key=None, user=None, dry_run: bool = False): cache_key = _cache_key(request, action=action, rate=rate, key=key, user=user) history = cache.get(cache_key, []) now = time.time() while history and history[-1] <= now - rate.duration: history.pop() allowed = len(history) < rate.amount if allowed and not dry_run: history.insert(0, now) cache.set(cache_key, history, rate.duration) return allowed def _handler429(request): from allauth.account import app_settings return render(request, "429." + app_settings.TEMPLATE_EXTENSION, status=429) def respond_429(request) -> HttpResponse: if app_settings.HEADLESS_ENABLED and hasattr(request.allauth, "headless"): from allauth.headless.base.response import RateLimitResponse return RateLimitResponse(request) try: handler429 = import_callable(settings.ROOT_URLCONF + ".handler429") handler429 = import_callable(handler429) except (ImportError, AttributeError): handler429 = _handler429 return handler429(request) def consume_or_429(request, *args, **kwargs) -> Optional[HttpResponse]: if not consume(request, *args, **kwargs): return respond_429(request) return None django-allauth-65.0.2/allauth/core/tests/000077500000000000000000000000001467545753200202445ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/tests/__init__.py000066400000000000000000000000001467545753200223430ustar00rootroot00000000000000django-allauth-65.0.2/allauth/core/tests/test_ratelimit.py000066400000000000000000000012131467545753200236440ustar00rootroot00000000000000import pytest from allauth.core import ratelimit @pytest.mark.parametrize( "rate,values", [ ("5/m", [(5, 60, "ip")]), ("5/m/user", [(5, 60, "user")]), ("2/3.5m/key", [(2, 210, "key")]), ("3/5m/user,20/0.5m/ip", [(3, 300, "user"), (20, 30, "ip")]), ("7/2h", [(7, 7200, "ip")]), ("7/0.25d", [(7, 21600, "ip")]), ], ) def test_parse(rate, values): rates = ratelimit._parse_rates(rate) assert len(rates) == len(values) for i, rate in enumerate(rates): assert rate.amount == values[i][0] assert rate.duration == values[i][1] assert rate.per == values[i][2] django-allauth-65.0.2/allauth/decorators.py000066400000000000000000000006631467545753200206760ustar00rootroot00000000000000from functools import wraps from allauth.core import ratelimit def rate_limit(*, action, **rl_kwargs): def decorator(function): @wraps(function) def wrap(request, *args, **kwargs): resp = ratelimit.consume_or_429(request, action=action, **rl_kwargs) if not resp: resp = function(request, *args, **kwargs) return resp return wrap return decorator django-allauth-65.0.2/allauth/exceptions.py000066400000000000000000000003021467545753200207000ustar00rootroot00000000000000import warnings from allauth.core.exceptions import ImmediateHttpResponse __all__ = ["ImmediateHttpResponse"] warnings.warn("allauth.exceptions is deprecated, use allauth.core.exceptions") django-allauth-65.0.2/allauth/headless/000077500000000000000000000000001467545753200177425ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/__init__.py000066400000000000000000000000001467545753200220410ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/account/000077500000000000000000000000001467545753200213765ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/account/__init__.py000066400000000000000000000000001467545753200234750ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/account/inputs.py000066400000000000000000000163711467545753200233020ustar00rootroot00000000000000from django.core.exceptions import ImproperlyConfigured from django.core.validators import validate_email from allauth.account import app_settings as account_app_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.forms import ( AddEmailForm, BaseSignupForm, ConfirmLoginCodeForm, ReauthenticateForm, RequestLoginCodeForm, ResetPasswordForm, UserTokenForm, ) from allauth.account.internal import flows from allauth.account.models import ( EmailAddress, Login, get_emailconfirmation_model, ) from allauth.core import context from allauth.headless.adapter import get_adapter from allauth.headless.internal.restkit import inputs class SignupInput(BaseSignupForm, inputs.Input): password = inputs.CharField() def clean_password(self): password = self.cleaned_data["password"] return get_account_adapter().clean_password(password) class LoginInput(inputs.Input): username = inputs.CharField(required=False) email = inputs.EmailField(required=False) password = inputs.CharField() def clean(self): cleaned_data = super().clean() username = None email = None if ( account_app_settings.AUTHENTICATION_METHOD == account_app_settings.AuthenticationMethod.USERNAME ): username = cleaned_data.get("username") missing_field = "username" elif ( account_app_settings.AUTHENTICATION_METHOD == account_app_settings.AuthenticationMethod.EMAIL ): email = cleaned_data.get("email") missing_field = "email" elif ( account_app_settings.AUTHENTICATION_METHOD == account_app_settings.AuthenticationMethod.USERNAME_EMAIL ): username = cleaned_data.get("username") email = cleaned_data.get("email") missing_field = "email" if email and username: raise get_adapter().validation_error("email_or_username") else: raise ImproperlyConfigured(account_app_settings.AUTHENTICATION_METHOD) if not email and not username: if not self.errors.get(missing_field): self.add_error( missing_field, get_adapter().validation_error("required") ) password = cleaned_data.get("password") if password and (username or email): credentials = {"password": password} if email: credentials["email"] = email auth_method = account_app_settings.AuthenticationMethod.EMAIL else: credentials["username"] = username auth_method = account_app_settings.AuthenticationMethod.USERNAME user = get_account_adapter().authenticate(context.request, **credentials) if user: self.login = Login(user=user, email=credentials.get("email")) if flows.login.is_login_rate_limited(context.request, self.login): raise get_account_adapter().validation_error( "too_many_login_attempts" ) else: error_code = "%s_password_mismatch" % auth_method.value self.add_error( "password", get_account_adapter().validation_error(error_code) ) return cleaned_data class VerifyEmailInput(inputs.Input): key = inputs.CharField() def clean_key(self): key = self.cleaned_data["key"] model = get_emailconfirmation_model() confirmation = model.from_key(key) valid = confirmation and not confirmation.key_expired() if not valid: raise get_account_adapter().validation_error( "incorrect_code" if account_app_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED else "invalid_or_expired_key" ) if valid and not confirmation.email_address.can_set_verified(): raise get_account_adapter().validation_error("email_taken") return confirmation class RequestPasswordResetInput(ResetPasswordForm, inputs.Input): pass class ResetPasswordKeyInput(inputs.Input): key = inputs.CharField() def __init__(self, *args, **kwargs): self.user = None super().__init__(*args, **kwargs) def clean_key(self): key = self.cleaned_data["key"] uidb36, _, subkey = key.partition("-") token_form = UserTokenForm(data={"uidb36": uidb36, "key": subkey}) if not token_form.is_valid(): raise get_account_adapter().validation_error("invalid_password_reset") self.user = token_form.reset_user return key class ResetPasswordInput(ResetPasswordKeyInput): password = inputs.CharField() def clean(self): cleaned_data = super().clean() password = self.cleaned_data.get("password") if self.user and password is not None: get_account_adapter().clean_password(password, user=self.user) return cleaned_data class ChangePasswordInput(inputs.Input): current_password = inputs.CharField(required=False) new_password = inputs.CharField() def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) self.fields["current_password"].required = self.user.has_usable_password() def clean_current_password(self): current_password = self.cleaned_data["current_password"] if current_password: if not self.user.check_password(current_password): raise get_account_adapter().validation_error("enter_current_password") return current_password def clean_new_password(self): new_password = self.cleaned_data["new_password"] adapter = get_account_adapter() return adapter.clean_password(new_password, user=self.user) class AddEmailInput(AddEmailForm, inputs.Input): pass class SelectEmailInput(inputs.Input): email = inputs.CharField() def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) def clean_email(self): email = self.cleaned_data["email"] validate_email(email) try: return EmailAddress.objects.get_for_user(user=self.user, email=email) except EmailAddress.DoesNotExist: raise get_adapter().validation_error("unknown_email") class DeleteEmailInput(SelectEmailInput): def clean_email(self): email = super().clean_email() if not flows.manage_email.can_delete_email(email): raise get_account_adapter().validation_error("cannot_remove_primary_email") return email class MarkAsPrimaryEmailInput(SelectEmailInput): primary = inputs.BooleanField(required=True) def clean_email(self): email = super().clean_email() if not flows.manage_email.can_mark_as_primary(email): raise get_account_adapter().validation_error("unverified_primary_email") return email class ReauthenticateInput(ReauthenticateForm, inputs.Input): pass class RequestLoginCodeInput(RequestLoginCodeForm, inputs.Input): pass class ConfirmLoginCodeInput(ConfirmLoginCodeForm, inputs.Input): pass django-allauth-65.0.2/allauth/headless/account/response.py000066400000000000000000000024711467545753200236120ustar00rootroot00000000000000from allauth.headless.adapter import get_adapter from allauth.headless.base.response import APIResponse class RequestEmailVerificationResponse(APIResponse): def __init__(self, request, verification_sent): super().__init__(request, status=200 if verification_sent else 403) class VerifyEmailResponse(APIResponse): def __init__(self, request, verification, stage): adapter = get_adapter() data = { "email": verification.email_address.email, "user": adapter.serialize_user(verification.email_address.user), } meta = { "is_authenticating": stage is not None, } super().__init__(request, data=data, meta=meta) class EmailAddressesResponse(APIResponse): def __init__(self, request, email_addresses): data = [ { "email": addr.email, "verified": addr.verified, "primary": addr.primary, } for addr in email_addresses ] super().__init__(request, data=data) class RequestPasswordResponse(APIResponse): pass class PasswordResetKeyResponse(APIResponse): def __init__(self, request, user): adapter = get_adapter() data = {"user": adapter.serialize_user(user)} super().__init__(request, data=data) django-allauth-65.0.2/allauth/headless/account/tests/000077500000000000000000000000001467545753200225405ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/account/tests/__init__.py000066400000000000000000000000001467545753200246370ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/account/tests/test_change_email.py000066400000000000000000000065201467545753200265500ustar00rootroot00000000000000from allauth.account.models import EmailAddress def test_list_email(auth_client, user, headless_reverse): resp = auth_client.get( headless_reverse("headless:account:manage_email"), ) assert len(resp.json()["data"]) == 1 def test_remove_email(auth_client, user, email_factory, headless_reverse): addr = EmailAddress.objects.create(email=email_factory(), user=user) assert EmailAddress.objects.filter(user=user).count() == 2 resp = auth_client.delete( headless_reverse("headless:account:manage_email"), data={"email": addr.email}, content_type="application/json", ) assert resp.status_code == 200 assert len(resp.json()["data"]) == 1 assert not EmailAddress.objects.filter(pk=addr.pk).exists() def test_add_email(auth_client, user, email_factory, headless_reverse): new_email = email_factory() resp = auth_client.post( headless_reverse("headless:account:manage_email"), data={"email": new_email}, content_type="application/json", ) assert resp.status_code == 200 assert len(resp.json()["data"]) == 2 assert EmailAddress.objects.filter(email=new_email, verified=False).exists() def test_change_primary(auth_client, user, email_factory, headless_reverse): addr = EmailAddress.objects.create( email=email_factory(), user=user, verified=True, primary=False ) resp = auth_client.patch( headless_reverse("headless:account:manage_email"), data={"email": addr.email, "primary": True}, content_type="application/json", ) assert resp.status_code == 200 assert len(resp.json()["data"]) == 2 assert EmailAddress.objects.filter(pk=addr.pk, primary=True).exists() def test_resend_verification( auth_client, user, email_factory, headless_reverse, mailoutbox ): addr = EmailAddress.objects.create(email=email_factory(), user=user, verified=False) resp = auth_client.put( headless_reverse("headless:account:manage_email"), data={"email": addr.email}, content_type="application/json", ) assert resp.status_code == 200 assert len(mailoutbox) == 1 def test_email_rate_limit( auth_client, user, email_factory, headless_reverse, settings, enable_cache ): settings.ACCOUNT_RATE_LIMITS = {"manage_email": "1/m/ip"} for attempt in range(2): new_email = email_factory() resp = auth_client.post( headless_reverse("headless:account:manage_email"), data={"email": new_email}, content_type="application/json", ) expected_status = 200 if attempt == 0 else 429 assert resp.status_code == expected_status assert resp.json()["status"] == expected_status def test_resend_verification_rate_limit( auth_client, user, email_factory, headless_reverse, settings, enable_cache, mailoutbox, ): settings.ACCOUNT_RATE_LIMITS = {"confirm_email": "1/m/ip"} for attempt in range(2): addr = EmailAddress.objects.create( email=email_factory(), user=user, verified=False ) resp = auth_client.put( headless_reverse("headless:account:manage_email"), data={"email": addr.email}, content_type="application/json", ) assert resp.status_code == 403 if attempt else 200 assert len(mailoutbox) == 1 django-allauth-65.0.2/allauth/headless/account/tests/test_change_password.py000066400000000000000000000142631467545753200273260ustar00rootroot00000000000000import copy from unittest.mock import ANY import pytest @pytest.mark.parametrize( "has_password,request_data,response_data,status_code", [ # Wrong current password ( True, {"current_password": "wrong", "new_password": "{password_factory}"}, { "status": 400, "errors": [ { "param": "current_password", "message": "Please type your current password.", "code": "enter_current_password", } ], }, 400, ), # Happy flow, regular password change ( True, { "current_password": "{user_password}", "new_password": "{password_factory}", }, { "status": 200, "meta": {"is_authenticated": True}, "data": { "user": ANY, "methods": [], }, }, 200, ), # New password does not match constraints ( True, { "current_password": "{user_password}", "new_password": "a", }, { "status": 400, "errors": [ { "param": "new_password", "code": "password_too_short", "message": "This password is too short. It must contain at least 6 characters.", } ], }, 400, ), # New password not empty ( True, { "current_password": "{user_password}", "new_password": "", }, { "status": 400, "errors": [ { "param": "new_password", "code": "required", "message": "This field is required.", } ], }, 400, ), # Current password not blank ( True, { "current_password": "", "new_password": "{password_factory}", }, { "status": 400, "errors": [ { "param": "current_password", "message": "This field is required.", "code": "required", } ], }, 400, ), # Current password missing ( True, { "new_password": "{password_factory}", }, { "status": 400, "errors": [ { "param": "current_password", "message": "This field is required.", "code": "required", } ], }, 400, ), # Current password not set, happy flow ( False, { "current_password": "", "new_password": "{password_factory}", }, { "status": 200, "meta": {"is_authenticated": True}, "data": { "user": ANY, "methods": [], }, }, 200, ), # Current password not set, current_password absent ( False, { "new_password": "{password_factory}", }, { "status": 200, "meta": {"is_authenticated": True}, "data": { "user": ANY, "methods": [], }, }, 200, ), ], ) def test_change_password( auth_client, user, request_data, response_data, status_code, has_password, user_password, password_factory, settings, mailoutbox, headless_reverse, headless_client, ): request_data = copy.deepcopy(request_data) response_data = copy.deepcopy(response_data) settings.ACCOUNT_EMAIL_NOTIFICATIONS = True if not has_password: user.set_unusable_password() user.save(update_fields=["password"]) auth_client.force_login(user) if request_data.get("current_password") == "{user_password}": request_data["current_password"] = user_password if request_data.get("new_password") == "{password_factory}": request_data["new_password"] = password_factory() resp = auth_client.post( headless_reverse("headless:account:change_password"), data=request_data, content_type="application/json", ) assert resp.status_code == status_code resp_json = resp.json() if headless_client == "app" and resp.status_code == 200: response_data["meta"]["session_token"] = ANY assert resp_json == response_data user.refresh_from_db() if resp.status_code == 200: assert user.check_password(request_data["new_password"]) assert len(mailoutbox) == 1 else: assert user.check_password(user_password) assert len(mailoutbox) == 0 def test_change_password_rate_limit( enable_cache, auth_client, user, user_password, password_factory, settings, headless_reverse, ): settings.ACCOUNT_RATE_LIMITS = {"change_password": "1/m/ip"} for attempt in range(2): new_password = password_factory() resp = auth_client.post( headless_reverse("headless:account:change_password"), data={ "current_password": user_password, "new_password": new_password, }, content_type="application/json", ) user_password = new_password expected_status = 200 if attempt == 0 else 429 assert resp.status_code == expected_status assert resp.json()["status"] == expected_status django-allauth-65.0.2/allauth/headless/account/tests/test_email_verification.py000066400000000000000000000054741467545753200300140ustar00rootroot00000000000000from allauth.account.models import ( EmailAddress, EmailConfirmationHMAC, get_emailconfirmation_model, ) from allauth.headless.constants import Flow def test_verify_email_other_user(auth_client, user, user_factory, headless_reverse): other_user = user_factory(email_verified=False) email_address = EmailAddress.objects.get(user=other_user, verified=False) assert not email_address.verified key = EmailConfirmationHMAC(email_address).key resp = auth_client.post( headless_reverse("headless:account:verify_email"), data={"key": key}, content_type="application/json", ) assert resp.status_code == 200 data = resp.json() # We're still authenticated as the user originally logged in, not the # other_user. assert data["data"]["user"]["id"] == user.pk def test_auth_unverified_email( client, user_factory, password_factory, settings, headless_reverse ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" password = password_factory() user = user_factory(email_verified=False, password=password) resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": password, }, content_type="application/json", ) assert resp.status_code == 401 data = resp.json() flows = data["data"]["flows"] assert [f for f in flows if f["id"] == Flow.VERIFY_EMAIL][0]["is_pending"] emailaddress = EmailAddress.objects.filter(user=user, verified=False).get() key = get_emailconfirmation_model().create(emailaddress).key resp = client.post( headless_reverse("headless:account:verify_email"), data={"key": key}, content_type="application/json", ) assert resp.status_code == 200 def test_verify_email_bad_key( client, settings, password_factory, user_factory, headless_reverse ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" password = password_factory() user = user_factory(email_verified=False, password=password) resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": password, }, content_type="application/json", ) assert resp.status_code == 401 resp = client.post( headless_reverse("headless:account:verify_email"), data={"key": "bad"}, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "code": "invalid_or_expired_key", "param": "key", "message": "Invalid or expired key.", } ], } django-allauth-65.0.2/allauth/headless/account/tests/test_email_verification_by_code.py000066400000000000000000000026631467545753200314750ustar00rootroot00000000000000from allauth.headless.constants import Flow def test_email_verification_rate_limits( client, db, user_password, settings, user_factory, password_factory, enable_cache, headless_reverse, ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_RATE_LIMITS = {"confirm_email": "1/m/key"} email = "user@email.org" user_factory(email=email, email_verified=False, password=user_password) for attempt in range(2): resp = client.post( headless_reverse("headless:account:login"), data={ "email": email, "password": user_password, }, content_type="application/json", ) if attempt == 0: assert resp.status_code == 401 flow = [ flow for flow in resp.json()["data"]["flows"] if flow.get("is_pending") ][0] assert flow["id"] == Flow.VERIFY_EMAIL else: assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "message": "Too many failed login attempts. Try again later.", "code": "too_many_login_attempts", } ], } django-allauth-65.0.2/allauth/headless/account/tests/test_login.py000066400000000000000000000127621467545753200252710ustar00rootroot00000000000000from unittest.mock import ANY import pytest def test_auth_password_input_error(headless_reverse, client): resp = client.post( headless_reverse("headless:account:login"), data={}, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "message": "This field is required.", "code": "required", "param": "password", }, { "message": "This field is required.", "code": "required", "param": "username", }, ], } def test_auth_password_bad_password(headless_reverse, client, user, settings): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": "wrong", }, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "param": "password", "message": "The email address and/or password you specified are not correct.", "code": "email_password_mismatch", } ], } def test_auth_password_success( client, user, user_password, settings, headless_reverse, headless_client ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" login_resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": user_password, }, content_type="application/json", ) assert login_resp.status_code == 200 session_resp = client.get( headless_reverse("headless:account:current_session"), content_type="application/json", ) assert session_resp.status_code == 200 for resp in [login_resp, session_resp]: extra_meta = {} if headless_client == "app" and resp == login_resp: # The session is created on first login, and hence the token is # exposed only at that moment. extra_meta["session_token"] = ANY assert resp.json() == { "status": 200, "data": { "user": { "id": user.pk, "display": str(user), "email": user.email, "username": user.username, "has_usable_password": True, }, "methods": [ { "at": ANY, "email": user.email, "method": "password", } ], }, "meta": {"is_authenticated": True, **extra_meta}, } @pytest.mark.parametrize("is_active,status_code", [(False, 401), (True, 200)]) def test_auth_password_user_inactive( client, user, user_password, settings, status_code, is_active, headless_reverse ): user.is_active = is_active user.save(update_fields=["is_active"]) resp = client.post( headless_reverse("headless:account:login"), data={ "username": user.username, "password": user_password, }, content_type="application/json", ) assert resp.status_code == status_code def test_login_failed_rate_limit( client, user, settings, headless_reverse, headless_client, enable_cache, ): settings.ACCOUNT_RATE_LIMITS = {"login_failed": "1/m/ip"} settings.ACCOUNT_AUTHENTICATION_METHOD = "email" for attempt in range(2): resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": "wrong", }, content_type="application/json", ) assert resp.status_code == 400 assert resp.json()["errors"] == [ ( { "code": "email_password_mismatch", "message": "The email address and/or password you specified are not correct.", "param": "password", } if attempt == 0 else { "message": "Too many failed login attempts. Try again later.", "code": "too_many_login_attempts", } ) ] def test_login_rate_limit( client, user, user_password, settings, headless_reverse, headless_client, enable_cache, ): settings.ACCOUNT_RATE_LIMITS = {"login": "1/m/ip"} settings.ACCOUNT_AUTHENTICATION_METHOD = "email" for attempt in range(2): resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": user_password, }, content_type="application/json", ) expected_status = 429 if attempt else 200 assert resp.status_code == expected_status def test_login_already_logged_in( auth_client, user, user_password, settings, headless_reverse ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" resp = auth_client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": user_password, }, content_type="application/json", ) assert resp.status_code == 409 django-allauth-65.0.2/allauth/headless/account/tests/test_login_by_code.py000066400000000000000000000077701467545753200267600ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.headless.constants import Flow def test_login_by_code(headless_reverse, user, client, mailoutbox): resp = client.post( headless_reverse("headless:account:request_login_code"), data={"email": user.email}, content_type="application/json", ) assert resp.status_code == 401 data = resp.json() assert [f for f in data["data"]["flows"] if f["id"] == Flow.LOGIN_BY_CODE][0][ "is_pending" ] assert len(mailoutbox) == 1 code = [line for line in mailoutbox[0].body.splitlines() if len(line) == 6][0] resp = client.post( headless_reverse("headless:account:confirm_login_code"), data={"code": code}, content_type="application/json", ) assert resp.status_code == 200 data = resp.json() assert data["meta"]["is_authenticated"] def test_login_by_code_rate_limit( headless_reverse, user, client, mailoutbox, settings, enable_cache ): settings.ACCOUNT_RATE_LIMITS = {"request_login_code": "1/m/ip"} for attempt in range(2): resp = client.post( headless_reverse("headless:account:request_login_code"), data={"email": user.email}, content_type="application/json", ) expected_code = 400 if attempt else 401 assert resp.status_code == expected_code data = resp.json() assert data["status"] == expected_code if expected_code == 400: assert data["errors"] == [ { "code": "too_many_login_attempts", "message": "Too many failed login attempts. Try again later.", "param": "email", }, ] def test_login_by_code_max_attemps(headless_reverse, user, client, settings): settings.ACCOUNT_LOGIN_BY_CODE_MAX_ATTEMPTS = 2 resp = client.post( headless_reverse("headless:account:request_login_code"), data={"email": user.email}, content_type="application/json", ) assert resp.status_code == 401 for i in range(3): resp = client.post( headless_reverse("headless:account:confirm_login_code"), data={"code": "wrong"}, content_type="application/json", ) session_resp = client.get( headless_reverse("headless:account:current_session"), data={"code": "wrong"}, content_type="application/json", ) assert session_resp.status_code == 401 pending_flows = [ f for f in session_resp.json()["data"]["flows"] if f.get("is_pending") ] if i >= 1: assert resp.status_code == 409 if i >= 2 else 400 assert len(pending_flows) == 0 else: assert resp.status_code == 400 assert len(pending_flows) == 1 def test_login_by_code_required( client, settings, user_factory, password_factory, headless_reverse, mailoutbox ): settings.ACCOUNT_LOGIN_BY_CODE_REQUIRED = True password = password_factory() user = user_factory(password=password, email_verified=False) email_address = EmailAddress.objects.get(email=user.email) assert not email_address.verified resp = client.post( headless_reverse("headless:account:login"), data={ "username": user.username, "password": password, }, content_type="application/json", ) assert resp.status_code == 401 pending_flow = [f for f in resp.json()["data"]["flows"] if f.get("is_pending")][0][ "id" ] assert pending_flow == Flow.LOGIN_BY_CODE code = [line for line in mailoutbox[0].body.splitlines() if len(line) == 6][0] resp = client.post( headless_reverse("headless:account:confirm_login_code"), data={"code": code}, content_type="application/json", ) assert resp.status_code == 200 data = resp.json() assert data["meta"]["is_authenticated"] email_address.refresh_from_db() assert email_address.verified django-allauth-65.0.2/allauth/headless/account/tests/test_reauthentication.py000066400000000000000000000030441467545753200275200ustar00rootroot00000000000000def test_reauthenticate( auth_client, user, user_password, headless_reverse, headless_client ): resp = auth_client.get( headless_reverse("headless:account:current_session"), content_type="application/json", ) assert resp.status_code == 200 data = resp.json() method_count = len(data["data"]["methods"]) resp = auth_client.post( headless_reverse("headless:account:reauthenticate"), data={ "password": user_password, }, content_type="application/json", ) assert resp.status_code == 200 resp = auth_client.get( headless_reverse("headless:account:current_session"), content_type="application/json", ) assert resp.status_code == 200 data = resp.json() assert len(data["data"]["methods"]) == method_count + 1 last_method = data["data"]["methods"][-1] assert last_method["method"] == "password" def test_reauthenticate_rate_limit( auth_client, user, user_password, headless_reverse, headless_client, settings, enable_cache, ): settings.ACCOUNT_RATE_LIMITS = {"reauthenticate": "1/m/ip"} for attempt in range(4): resp = auth_client.post( headless_reverse("headless:account:reauthenticate"), data={ "password": user_password, }, content_type="application/json", ) expected_status = 429 if attempt else 200 assert resp.status_code == expected_status assert resp.json()["status"] == expected_status django-allauth-65.0.2/allauth/headless/account/tests/test_reset_password.py000066400000000000000000000105201467545753200272130ustar00rootroot00000000000000from django.urls import reverse import pytest def test_password_reset_flow( client, user, mailoutbox, password_factory, settings, headless_reverse ): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True resp = client.post( headless_reverse("headless:account:request_password_reset"), data={ "email": user.email, }, content_type="application/json", ) assert resp.status_code == 200 assert len(mailoutbox) == 1 body = mailoutbox[0].body # Extract URL for `password_reset_from_key` view url = body[body.find("/password/reset/") :].split()[0] key = url.split("/")[-2] password = password_factory() # Too simple password resp = client.post( headless_reverse("headless:account:reset_password"), data={ "key": key, "password": "a", }, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "code": "password_too_short", "message": "This password is too short. It must contain at least 6 characters.", } ], } assert len(mailoutbox) == 1 # Success resp = client.post( headless_reverse("headless:account:reset_password"), data={ "key": key, "password": password, }, content_type="application/json", ) assert resp.status_code == 401 user.refresh_from_db() assert user.check_password(password) assert len(mailoutbox) == 2 # The security notification @pytest.mark.parametrize("method", ["get", "post"]) def test_password_reset_flow_wrong_key( client, password_factory, headless_reverse, method ): password = password_factory() if method == "get": resp = client.get( headless_reverse("headless:account:reset_password"), HTTP_X_PASSWORD_RESET_KEY="wrong", ) else: resp = client.post( headless_reverse("headless:account:reset_password"), data={ "key": "wrong", "password": password, }, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "param": "key", "code": "invalid_password_reset", "message": "The password reset token was invalid.", } ], } def test_password_reset_flow_unknown_user( client, db, mailoutbox, password_factory, settings, headless_reverse ): resp = client.post( headless_reverse("headless:account:request_password_reset"), data={ "email": "not@registered.org", }, content_type="application/json", ) assert resp.status_code == 200 assert len(mailoutbox) == 1 body = mailoutbox[0].body if getattr(settings, "HEADLESS_ONLY", False): assert settings.HEADLESS_FRONTEND_URLS["account_signup"] in body else: assert reverse("account_signup") in body def test_reset_password_rate_limit( auth_client, user, headless_reverse, settings, enable_cache ): settings.ACCOUNT_RATE_LIMITS = {"reset_password": "1/m/ip"} for attempt in range(2): resp = auth_client.post( headless_reverse("headless:account:request_password_reset"), data={"email": user.email}, content_type="application/json", ) expected_status = 200 if attempt == 0 else 429 assert resp.status_code == expected_status assert resp.json()["status"] == expected_status def test_password_reset_key_rate_limit( client, user, settings, headless_reverse, password_reset_key_generator, enable_cache, ): settings.ACCOUNT_RATE_LIMITS = {"reset_password_from_key": "1/m/ip"} for attempt in range(2): resp = client.post( headless_reverse("headless:account:reset_password"), data={ "key": password_reset_key_generator(user), "password": "a", # too short }, content_type="application/json", ) expected_status = 429 if attempt else 400 assert resp.status_code == expected_status assert resp.json()["status"] == expected_status django-allauth-65.0.2/allauth/headless/account/tests/test_session.py000066400000000000000000000023721467545753200256400ustar00rootroot00000000000000from django.test.client import Client from django.urls import reverse def test_app_session_gone(db, user): # intentionally use a vanilla Django test client client = Client() # Force login, creates a Django session client.force_login(user) # That Django session should not play any role. resp = client.get( reverse("headless:app:account:current_session"), HTTP_X_SESSION_TOKEN="gone" ) assert resp.status_code == 410 def test_logout(auth_client, headless_reverse): # That Django session should not play any role. resp = auth_client.get(headless_reverse("headless:account:current_session")) assert resp.status_code == 200 resp = auth_client.delete(headless_reverse("headless:account:current_session")) assert resp.status_code == 401 resp = auth_client.get(headless_reverse("headless:account:current_session")) assert resp.status_code in [401, 410] def test_logout_no_token(app_client, user): app_client.force_login(user) resp = app_client.get(reverse("headless:app:account:current_session")) assert resp.status_code == 200 resp = app_client.delete(reverse("headless:app:account:current_session")) assert resp.status_code == 401 assert "session_token" not in resp.json()["meta"] django-allauth-65.0.2/allauth/headless/account/tests/test_signup.py000066400000000000000000000120551467545753200254610ustar00rootroot00000000000000from unittest.mock import ANY, patch from django.contrib.auth.models import User from allauth.account.models import EmailAddress, EmailConfirmationHMAC from allauth.headless.constants import Flow def test_signup( db, client, email_factory, password_factory, settings, headless_reverse, headless_client, ): resp = client.post( headless_reverse("headless:account:signup"), data={ "username": "wizard", "email": email_factory(), "password": password_factory(), }, content_type="application/json", ) assert resp.status_code == 200 assert User.objects.filter(username="wizard").exists() def test_signup_with_email_verification( db, client, email_factory, password_factory, settings, headless_reverse, headless_client, ): settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_USERNAME_REQUIRED = False email = email_factory() resp = client.post( headless_reverse("headless:account:signup"), data={ "email": email, "password": password_factory(), }, content_type="application/json", ) assert resp.status_code == 401 assert User.objects.filter(email=email).exists() data = resp.json() flow = next((f for f in data["data"]["flows"] if f.get("is_pending"))) assert flow["id"] == "verify_email" addr = EmailAddress.objects.get(email=email) key = EmailConfirmationHMAC(addr).key resp = client.get( headless_reverse("headless:account:verify_email"), HTTP_X_EMAIL_VERIFICATION_KEY=key, ) assert resp.status_code == 200 assert resp.json() == { "data": { "email": email, "user": ANY, }, "meta": {"is_authenticating": True}, "status": 200, } resp = client.post( headless_reverse("headless:account:verify_email"), data={"key": key}, content_type="application/json", ) assert resp.status_code == 200 data = resp.json() assert data["meta"]["is_authenticated"] addr.refresh_from_db() assert addr.verified def test_signup_prevent_enumeration( db, client, email_factory, password_factory, settings, headless_reverse, headless_client, user, mailoutbox, ): settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_PREVENT_ENUMERATION = True resp = client.post( headless_reverse("headless:account:signup"), data={ "email": user.email, "password": password_factory(), }, content_type="application/json", ) assert len(mailoutbox) == 1 assert "an account using that email address already exists" in mailoutbox[0].body assert resp.status_code == 401 data = resp.json() assert [f for f in data["data"]["flows"] if f["id"] == Flow.VERIFY_EMAIL][0][ "is_pending" ] resp = client.get(headless_reverse("headless:account:current_session")) data = resp.json() assert [f for f in data["data"]["flows"] if f["id"] == Flow.VERIFY_EMAIL][0][ "is_pending" ] def test_signup_rate_limit( db, client, email_factory, password_factory, settings, headless_reverse, enable_cache, headless_client, ): settings.ACCOUNT_RATE_LIMITS = {"signup": "1/m/ip"} for attempt in range(2): resp = client.post( headless_reverse("headless:account:signup"), data={ "username": f"wizard{attempt}", "email": email_factory(), "password": password_factory(), }, content_type="application/json", ) expected_status = 429 if attempt else 200 assert resp.status_code == expected_status assert resp.json()["status"] == expected_status def test_signup_closed( db, client, email_factory, password_factory, settings, headless_reverse, headless_client, ): with patch( "allauth.account.adapter.DefaultAccountAdapter.is_open_for_signup" ) as iofs: iofs.return_value = False resp = client.post( headless_reverse("headless:account:signup"), data={ "username": "wizard", "email": email_factory(), "password": password_factory(), }, content_type="application/json", ) assert resp.status_code == 403 assert not User.objects.filter(username="wizard").exists() def test_signup_while_logged_in( db, auth_client, email_factory, password_factory, settings, headless_reverse, headless_client, ): resp = auth_client.post( headless_reverse("headless:account:signup"), data={ "username": "wizard", "email": email_factory(), "password": password_factory(), }, content_type="application/json", ) assert resp.status_code == 409 assert resp.json() == {"status": 409} django-allauth-65.0.2/allauth/headless/account/urls.py000066400000000000000000000057561467545753200227520ustar00rootroot00000000000000from django.urls import include, path from allauth import app_settings as allauth_settings from allauth.account import app_settings as account_settings from allauth.headless.account import views def build_urlpatterns(client): account_patterns = [] auth_patterns = [ path( "session", views.SessionView.as_api_view(client=client), name="current_session", ), path( "reauthenticate", views.ReauthenticateView.as_api_view(client=client), name="reauthenticate", ), path( "code/confirm", views.ConfirmLoginCodeView.as_api_view(client=client), name="confirm_login_code", ), ] if not allauth_settings.SOCIALACCOUNT_ONLY: account_patterns.extend( [ path( "password/change", views.ChangePasswordView.as_api_view(client=client), name="change_password", ), path( "email", views.ManageEmailView.as_api_view(client=client), name="manage_email", ), ] ) auth_patterns.extend( [ path( "password/", include( [ path( "request", views.RequestPasswordResetView.as_api_view( client=client ), name="request_password_reset", ), path( "reset", views.ResetPasswordView.as_api_view(client=client), name="reset_password", ), ] ), ), path( "login", views.LoginView.as_api_view(client=client), name="login", ), path( "signup", views.SignupView.as_api_view(client=client), name="signup", ), path( "email/verify", views.VerifyEmailView.as_api_view(client=client), name="verify_email", ), ] ) if account_settings.LOGIN_BY_CODE_ENABLED: auth_patterns.extend( [ path( "code/request", views.RequestLoginCodeView.as_api_view(client=client), name="request_login_code", ), ] ) return [ path("auth/", include(auth_patterns)), path( "account/", include(account_patterns), ), ] django-allauth-65.0.2/allauth/headless/account/views.py000066400000000000000000000215671467545753200231200ustar00rootroot00000000000000from django.utils.decorators import method_decorator from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal import flows from allauth.account.internal.flows import password_change, password_reset from allauth.account.models import EmailAddress from allauth.account.stages import EmailVerificationStage, LoginStageController from allauth.account.utils import send_email_confirmation from allauth.core import ratelimit from allauth.core.exceptions import ImmediateHttpResponse from allauth.decorators import rate_limit from allauth.headless.account import response from allauth.headless.account.inputs import ( AddEmailInput, ChangePasswordInput, ConfirmLoginCodeInput, DeleteEmailInput, LoginInput, MarkAsPrimaryEmailInput, ReauthenticateInput, RequestLoginCodeInput, RequestPasswordResetInput, ResetPasswordInput, ResetPasswordKeyInput, SelectEmailInput, SignupInput, VerifyEmailInput, ) from allauth.headless.base.response import ( APIResponse, AuthenticationResponse, ConflictResponse, ForbiddenResponse, ) from allauth.headless.base.views import APIView, AuthenticatedAPIView from allauth.headless.internal import authkit from allauth.headless.internal.restkit.response import ErrorResponse class RequestLoginCodeView(APIView): input_class = RequestLoginCodeInput def post(self, request, *args, **kwargs): flows.login_by_code.request_login_code( self.request, self.input.cleaned_data["email"] ) return AuthenticationResponse(self.request) class ConfirmLoginCodeView(APIView): input_class = ConfirmLoginCodeInput def dispatch(self, request, *args, **kwargs): auth_status = authkit.AuthenticationStatus(request) self.stage = auth_status.get_pending_stage() if not self.stage: return ConflictResponse(request) self.user, self.pending_login = flows.login_by_code.get_pending_login( request, self.stage.login, peek=True ) return super().dispatch(request, *args, **kwargs) def post(self, request, *args, **kwargs): flows.login_by_code.perform_login_by_code(self.request, self.stage, None) return AuthenticationResponse(request) def get_input_kwargs(self): kwargs = super().get_input_kwargs() kwargs["code"] = ( self.pending_login.get("code", "") if self.pending_login else "" ) return kwargs def handle_invalid_input(self, input): flows.login_by_code.record_invalid_attempt(self.request, self.stage.login) return super().handle_invalid_input(input) @method_decorator(rate_limit(action="login"), name="handle") class LoginView(APIView): input_class = LoginInput def post(self, request, *args, **kwargs): if request.user.is_authenticated: return ConflictResponse(request) credentials = self.input.cleaned_data flows.login.perform_password_login(request, credentials, self.input.login) return AuthenticationResponse(self.request) @method_decorator(rate_limit(action="signup"), name="handle") class SignupView(APIView): input_class = {"POST": SignupInput} by_passkey = False def post(self, request, *args, **kwargs): if request.user.is_authenticated: return ConflictResponse(request) if not get_account_adapter().is_open_for_signup(request): return ForbiddenResponse(request) user, resp = self.input.try_save(request) if not resp: try: flows.signup.complete_signup( request, user=user, by_passkey=self.by_passkey ) except ImmediateHttpResponse: pass return AuthenticationResponse(request) class SessionView(APIView): def get(self, request, *args, **kwargs): return AuthenticationResponse(request) def delete(self, request, *args, **kwargs): adapter = get_account_adapter() adapter.logout(request) return AuthenticationResponse(request) class VerifyEmailView(APIView): input_class = VerifyEmailInput def handle(self, request, *args, **kwargs): self.stage = LoginStageController.enter(request, EmailVerificationStage.key) return super().handle(request, *args, **kwargs) def get(self, request, *args, **kwargs): key = request.headers.get("x-email-verification-key", "") input = self.input_class({"key": key}) if not input.is_valid(): return ErrorResponse(request, input=input) verification = input.cleaned_data["key"] return response.VerifyEmailResponse(request, verification, stage=self.stage) def post(self, request, *args, **kwargs): confirmation = self.input.cleaned_data["key"] email_address = confirmation.confirm(request) if not email_address: # Should not happen, VerifyInputInput should have verified all # preconditions. return APIResponse(status=500) if self.stage: # Verifying email as part of login/signup flow, so emit a # authentication status response. self.stage.exit() return AuthenticationResponse(self.request) class RequestPasswordResetView(APIView): input_class = RequestPasswordResetInput def post(self, request, *args, **kwargs): r429 = ratelimit.consume_or_429( self.request, action="reset_password", key=self.input.cleaned_data["email"].lower(), ) if r429: return r429 self.input.save(request) return response.RequestPasswordResponse(request) @method_decorator(rate_limit(action="reset_password_from_key"), name="handle") class ResetPasswordView(APIView): input_class = ResetPasswordInput def get(self, request, *args, **kwargs): key = request.headers.get("X-Password-Reset-Key", "") input = ResetPasswordKeyInput({"key": key}) if not input.is_valid(): return ErrorResponse(request, input=input) return response.PasswordResetKeyResponse(request, input.user) def post(self, request, *args, **kwargs): flows.password_reset.reset_password( self.input.user, self.input.cleaned_data["password"] ) password_reset.finalize_password_reset(request, self.input.user) return AuthenticationResponse(self.request) @method_decorator(rate_limit(action="change_password"), name="handle") class ChangePasswordView(AuthenticatedAPIView): input_class = ChangePasswordInput def post(self, request, *args, **kwargs): password_change.change_password( self.request.user, self.input.cleaned_data["new_password"] ) is_set = not self.input.cleaned_data.get("current_password") if is_set: password_change.finalize_password_set(request, request.user) else: password_change.finalize_password_change(request, request.user) return AuthenticationResponse(request) def get_input_kwargs(self): return {"user": self.request.user} @method_decorator(rate_limit(action="manage_email"), name="handle") class ManageEmailView(AuthenticatedAPIView): input_class = { "POST": AddEmailInput, "PUT": SelectEmailInput, "DELETE": DeleteEmailInput, "PATCH": MarkAsPrimaryEmailInput, } def get(self, request, *args, **kwargs): return self._respond_email_list() def _respond_email_list(self): addrs = EmailAddress.objects.filter(user=self.request.user) return response.EmailAddressesResponse(self.request, addrs) def post(self, request, *args, **kwargs): flows.manage_email.add_email(request, self.input) return self._respond_email_list() def delete(self, request, *args, **kwargs): addr = self.input.cleaned_data["email"] flows.manage_email.delete_email(request, addr) return self._respond_email_list() def patch(self, request, *args, **kwargs): addr = self.input.cleaned_data["email"] flows.manage_email.mark_as_primary(request, addr) return self._respond_email_list() def put(self, request, *args, **kwargs): addr = self.input.cleaned_data["email"] sent = send_email_confirmation(request, request.user, email=addr.email) return response.RequestEmailVerificationResponse( request, verification_sent=sent ) def get_input_kwargs(self): return {"user": self.request.user} @method_decorator(rate_limit(action="reauthenticate"), name="handle") class ReauthenticateView(AuthenticatedAPIView): input_class = ReauthenticateInput def post(self, request, *args, **kwargs): flows.reauthentication.reauthenticate_by_password(self.request) return AuthenticationResponse(self.request) def get_input_kwargs(self): return {"user": self.request.user} django-allauth-65.0.2/allauth/headless/adapter.py000066400000000000000000000040611467545753200217350ustar00rootroot00000000000000from typing import Any, Dict from django.forms.fields import Field from allauth.account.models import EmailAddress from allauth.account.utils import user_display, user_username from allauth.core.internal.adapter import BaseAdapter from allauth.headless import app_settings from allauth.utils import import_attribute class DefaultHeadlessAdapter(BaseAdapter): """The adapter class allows you to override various functionality of the ``allauth.headless`` app. To do so, point ``settings.HEADLESS_ADAPTER`` to your own class that derives from ``DefaultHeadlessAdapter`` and override the behavior by altering the implementation of the methods according to your own need. """ error_messages = { # For the following error messages i18n is not an issue as these should not be # showing up in a UI. "account_not_found": "Unknown account.", "client_id_required": "`client_id` required.", "email_or_username": "Pass only one of email or username, not both.", "invalid_token": "Invalid token.", "token_authentication_not_supported": "Provider does not support token authentication.", "token_required": "`id_token` and/or `access_token` required.", "required": Field.default_error_messages["required"], "unknown_email": "Unknown email address.", "invalid_url": "Invalid URL.", } def serialize_user(self, user) -> Dict[str, Any]: """ Returns the basic user data. Note that this data is also exposed in partly authenticated scenario's (e.g. password reset, email verification). """ ret = { "id": user.pk, "display": user_display(user), "has_usable_password": user.has_usable_password(), } email = EmailAddress.objects.get_primary_email(user) if email: ret["email"] = email username = user_username(user) if username: ret["username"] = username return ret def get_adapter(): return import_attribute(app_settings.ADAPTER)() django-allauth-65.0.2/allauth/headless/app_settings.py000066400000000000000000000015771467545753200230260ustar00rootroot00000000000000class AppSettings: def __init__(self, prefix): self.prefix = prefix def _setting(self, name, dflt): from allauth.utils import get_setting return get_setting(self.prefix + name, dflt) @property def ADAPTER(self): return self._setting( "ADAPTER", "allauth.headless.adapter.DefaultHeadlessAdapter" ) @property def TOKEN_STRATEGY(self): from allauth.utils import import_attribute path = self._setting( "TOKEN_STRATEGY", "allauth.headless.tokens.sessions.SessionTokenStrategy" ) cls = import_attribute(path) return cls() @property def FRONTEND_URLS(self): return self._setting("FRONTEND_URLS", {}) _app_settings = AppSettings("HEADLESS_") def __getattr__(name): # See https://peps.python.org/pep-0562/ return getattr(_app_settings, name) django-allauth-65.0.2/allauth/headless/apps.py000066400000000000000000000002731467545753200212610ustar00rootroot00000000000000from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ class HeadlessConfig(AppConfig): name = "allauth.headless" verbose_name = _("Headless") django-allauth-65.0.2/allauth/headless/base/000077500000000000000000000000001467545753200206545ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/base/__init__.py000066400000000000000000000000001467545753200227530ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/base/response.py000066400000000000000000000131751467545753200230730ustar00rootroot00000000000000from allauth import app_settings as allauth_settings from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.authentication import get_authentication_records from allauth.account.internal import flows from allauth.account.internal.stagekit import LOGIN_SESSION_KEY from allauth.headless.adapter import get_adapter from allauth.headless.constants import Flow from allauth.headless.internal import authkit from allauth.headless.internal.restkit.response import APIResponse from allauth.mfa import app_settings as mfa_settings class BaseAuthenticationResponse(APIResponse): def __init__(self, request, user=None, status=None): data = {} if user and user.is_authenticated: adapter = get_adapter() data["user"] = adapter.serialize_user(user) data["methods"] = get_authentication_records(request) status = status or 200 else: status = status or 401 if status != 200: data["flows"] = self._get_flows(request, user) meta = { "is_authenticated": user and user.is_authenticated, } super().__init__( request, data=data, meta=meta, status=status, ) def _get_flows(self, request, user): auth_status = authkit.AuthenticationStatus(request) ret = [] if user and user.is_authenticated: ret.extend(flows.reauthentication.get_reauthentication_flows(user)) else: if not allauth_settings.SOCIALACCOUNT_ONLY: ret.append({"id": Flow.LOGIN}) if account_settings.LOGIN_BY_CODE_ENABLED: ret.append({"id": Flow.LOGIN_BY_CODE}) if ( get_account_adapter().is_open_for_signup(request) and not allauth_settings.SOCIALACCOUNT_ONLY ): ret.append({"id": Flow.SIGNUP}) if allauth_settings.SOCIALACCOUNT_ENABLED: from allauth.headless.socialaccount.response import ( provider_flows, ) ret.extend(provider_flows(request)) if allauth_settings.MFA_ENABLED: if mfa_settings.PASSKEY_LOGIN_ENABLED: ret.append({"id": Flow.MFA_LOGIN_WEBAUTHN}) stage_key = None stage = auth_status.get_pending_stage() if stage: stage_key = stage.key else: lsk = request.session.get(LOGIN_SESSION_KEY) if isinstance(lsk, str): stage_key = lsk if stage_key: pending_flow = {"id": stage_key, "is_pending": True} if stage and stage_key == Flow.MFA_AUTHENTICATE: self._enrich_mfa_flow(stage, pending_flow) self._upsert_pending_flow(ret, pending_flow) return ret def _upsert_pending_flow(self, flows, pending_flow): flow = next((flow for flow in flows if flow["id"] == pending_flow["id"]), None) if flow: flow.update(pending_flow) else: flows.append(pending_flow) def _enrich_mfa_flow(self, stage, flow: dict) -> None: from allauth.mfa.adapter import get_adapter as get_mfa_adapter from allauth.mfa.models import Authenticator adapter = get_mfa_adapter() types = [] for typ in Authenticator.Type: if adapter.is_mfa_enabled(stage.login.user, types=[typ]): types.append(typ) flow["types"] = types class AuthenticationResponse(BaseAuthenticationResponse): def __init__(self, request): super().__init__(request, user=request.user) class ReauthenticationResponse(BaseAuthenticationResponse): def __init__(self, request): super().__init__(request, user=request.user, status=401) class UnauthorizedResponse(BaseAuthenticationResponse): def __init__(self, request, status=401): super().__init__(request, user=None, status=status) class ForbiddenResponse(APIResponse): def __init__(self, request): super().__init__(request, status=403) class ConflictResponse(APIResponse): def __init__(self, request): super().__init__(request, status=409) def get_config_data(request): data = { "authentication_method": account_settings.AUTHENTICATION_METHOD, "is_open_for_signup": get_account_adapter().is_open_for_signup(request), "email_verification_by_code_enabled": account_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED, "login_by_code_enabled": account_settings.LOGIN_BY_CODE_ENABLED, } return {"account": data} class ConfigResponse(APIResponse): def __init__(self, request): data = get_config_data(request) if allauth_settings.SOCIALACCOUNT_ENABLED: from allauth.headless.socialaccount.response import ( get_config_data as get_socialaccount_config_data, ) data.update(get_socialaccount_config_data(request)) if allauth_settings.MFA_ENABLED: from allauth.headless.mfa.response import ( get_config_data as get_mfa_config_data, ) data.update(get_mfa_config_data(request)) if allauth_settings.USERSESSIONS_ENABLED: from allauth.headless.usersessions.response import ( get_config_data as get_usersessions_config_data, ) data.update(get_usersessions_config_data(request)) return super().__init__(request, data=data) class RateLimitResponse(APIResponse): def __init__(self, request): super().__init__(request, status=429) django-allauth-65.0.2/allauth/headless/base/tests/000077500000000000000000000000001467545753200220165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/base/tests/__init__.py000066400000000000000000000000001467545753200241150ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/base/tests/test_views.py000066400000000000000000000004461467545753200245700ustar00rootroot00000000000000def test_config(db, client, headless_reverse): resp = client.get(headless_reverse("headless:config")) assert resp.status_code == 200 data = resp.json() assert set(data["data"].keys()) == { "account", "mfa", "socialaccount", "usersessions", } django-allauth-65.0.2/allauth/headless/base/urls.py000066400000000000000000000003751467545753200222200ustar00rootroot00000000000000from django.urls import path from allauth.headless.base import views def build_urlpatterns(client): return [ path( "config", views.ConfigView.as_api_view(client=client), name="config", ), ] django-allauth-65.0.2/allauth/headless/base/views.py000066400000000000000000000041161467545753200223650ustar00rootroot00000000000000from typing import Optional, Type from django.utils.decorators import classonlymethod from allauth.account.stages import LoginStage, LoginStageController from allauth.core.exceptions import ReauthenticationRequired from allauth.headless.base import response from allauth.headless.constants import Client from allauth.headless.internal import decorators from allauth.headless.internal.restkit.views import RESTView class APIView(RESTView): client = None @classonlymethod def as_api_view(cls, **initkwargs): view_func = cls.as_view(**initkwargs) if initkwargs["client"] == Client.APP: view_func = decorators.app_view(view_func) else: view_func = decorators.browser_view(view_func) return view_func def dispatch(self, request, *args, **kwargs): try: return super().dispatch(request, *args, **kwargs) except ReauthenticationRequired: return response.ReauthenticationResponse(self.request) class AuthenticationStageAPIView(APIView): stage_class: Optional[Type[LoginStage]] = None def handle(self, request, *args, **kwargs): self.stage = LoginStageController.enter(request, self.stage_class.key) if not self.stage: return response.UnauthorizedResponse(request) return super().handle(request, *args, **kwargs) def respond_stage_error(self): return response.UnauthorizedResponse(self.request) def respond_next_stage(self): self.stage.exit() return response.AuthenticationResponse(self.request) class AuthenticatedAPIView(APIView): def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: return response.AuthenticationResponse(request) return super().dispatch(request, *args, **kwargs) class ConfigView(APIView): def get(self, request, *args, **kwargs): """ The frontend queries (GET) this endpoint, expecting to receive either a 401 if no user is authenticated, or user information. """ return response.ConfigResponse(request) django-allauth-65.0.2/allauth/headless/conftest.py000066400000000000000000000030451467545753200221430ustar00rootroot00000000000000from django.test.client import Client from django.urls import reverse import pytest @pytest.fixture(params=["app", "browser"]) def headless_client(request): return request.param @pytest.fixture def headless_reverse(headless_client): def rev(viewname, **kwargs): viewname = viewname.replace("headless:", f"headless:{headless_client}:") return reverse(viewname, **kwargs) return rev class AppClient(Client): session_token = None def generic(self, *args, **kwargs): if self.session_token: kwargs["HTTP_X_SESSION_TOKEN"] = self.session_token resp = super().generic(*args, **kwargs) if resp["content-type"] == "application/json": data = resp.json() session_token = data.get("meta", {}).get("session_token") if session_token: self.session_token = session_token return resp def force_login(self, user): ret = super().force_login(user) self.session_token = self.session.session_key return ret def headless_session(self): from allauth.headless.internal import sessionkit return sessionkit.session_store(self.session_token) @pytest.fixture def app_client(): return AppClient() @pytest.fixture def client(headless_client): if headless_client == "browser": client = Client() client.headless_session = lambda: client.session return client return AppClient() @pytest.fixture def auth_client(client, user): client.force_login(user) return client django-allauth-65.0.2/allauth/headless/constants.py000066400000000000000000000013251467545753200223310ustar00rootroot00000000000000from enum import Enum from allauth.account.stages import EmailVerificationStage, LoginByCodeStage class Client(str, Enum): APP = "app" BROWSER = "browser" class Flow(str, Enum): VERIFY_EMAIL = EmailVerificationStage.key LOGIN = "login" LOGIN_BY_CODE = LoginByCodeStage.key SIGNUP = "signup" PROVIDER_REDIRECT = "provider_redirect" PROVIDER_SIGNUP = "provider_signup" PROVIDER_TOKEN = "provider_token" REAUTHENTICATE = "reauthenticate" MFA_REAUTHENTICATE = "mfa_reauthenticate" MFA_AUTHENTICATE = "mfa_authenticate" # NOTE: Equal to `allauth.mfa.stages.AuthenticationStage.key` MFA_LOGIN_WEBAUTHN = "mfa_login_webauthn" MFA_SIGNUP_WEBAUTHN = "mfa_signup_webauthn" django-allauth-65.0.2/allauth/headless/internal/000077500000000000000000000000001467545753200215565ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/internal/__init__.py000066400000000000000000000000001467545753200236550ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/internal/authkit.py000066400000000000000000000055711467545753200236110ustar00rootroot00000000000000from contextlib import contextmanager from typing import Any, Dict, Optional from django.utils.functional import SimpleLazyObject, empty from allauth import app_settings as allauth_settings from allauth.account.internal.stagekit import get_pending_stage from allauth.core.exceptions import ImmediateHttpResponse from allauth.headless import app_settings from allauth.headless.constants import Client from allauth.headless.internal import sessionkit class AuthenticationStatus: def __init__(self, request): self.request = request @property def is_authenticated(self): return self.request.user.is_authenticated def get_pending_stage(self): return get_pending_stage(self.request) @property def has_pending_signup(self): if not allauth_settings.SOCIALACCOUNT_ENABLED: return False from allauth.socialaccount.internal import flows return bool(flows.signup.get_pending_signup(self.request)) def purge_request_user_cache(request): for attr in ["_cached_user", "_acached_user"]: if hasattr(request, attr): delattr(request, attr) if isinstance(request.user, SimpleLazyObject): request.user._wrapped = empty @contextmanager def authentication_context(request): from allauth.headless.base.response import UnauthorizedResponse old_user = request.user old_session = request.session try: request.session = sessionkit.new_session() purge_request_user_cache(request) strategy = app_settings.TOKEN_STRATEGY session_token = strategy.get_session_token(request) if session_token: session = strategy.lookup_session(session_token) if not session: raise ImmediateHttpResponse(UnauthorizedResponse(request, status=410)) request.session = session purge_request_user_cache(request) request.allauth.headless._pre_user = request.user # request.user is lazy -- force evaluation request.allauth.headless._pre_user.pk yield finally: if request.session.modified and not request.session.is_empty(): request.session.save() request.user = old_user request.session = old_session # e.g. logging in calls csrf `rotate_token()` -- this prevents setting a new CSRF cookie. request.META["CSRF_COOKIE_NEEDS_UPDATE"] = False def expose_access_token(request) -> Optional[Dict[str, Any]]: """ Determines if a new access token needs to be exposed. """ if request.allauth.headless.client != Client.APP: return None if not request.user.is_authenticated: return None pre_user = request.allauth.headless._pre_user if pre_user.is_authenticated and pre_user.pk == request.user.pk: return None strategy = app_settings.TOKEN_STRATEGY return strategy.create_access_token_payload(request) django-allauth-65.0.2/allauth/headless/internal/decorators.py000066400000000000000000000027351467545753200243040ustar00rootroot00000000000000from functools import wraps from types import SimpleNamespace from django.middleware.csrf import get_token from django.views.decorators.csrf import csrf_exempt from allauth.account.internal.decorators import login_not_required from allauth.headless.constants import Client from allauth.headless.internal import authkit def mark_request_as_headless(request, client): request.allauth.headless = SimpleNamespace() request.allauth.headless.client = client def app_view( function=None, ): def decorator(view_func): @login_not_required @wraps(view_func) def _wrapper_view(request, *args, **kwargs): mark_request_as_headless(request, Client.APP) with authkit.authentication_context(request): return view_func(request, *args, **kwargs) return _wrapper_view ret = decorator if function: ret = decorator(function) return csrf_exempt(ret) def browser_view( function=None, ): def decorator(view_func): @login_not_required @wraps(view_func) def _wrapper_view(request, *args, **kwargs): mark_request_as_headless(request, Client.BROWSER) # Needed -- so that the CSRF token is set in the response for the # frontend to pick up. get_token(request) return view_func(request, *args, **kwargs) return _wrapper_view ret = decorator if function: ret = decorator(function) return ret django-allauth-65.0.2/allauth/headless/internal/restkit/000077500000000000000000000000001467545753200232435ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/internal/restkit/__init__.py000066400000000000000000000000001467545753200253420ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/internal/restkit/inputs.py000066400000000000000000000005451467545753200251430ustar00rootroot00000000000000from django.forms import ( BooleanField, CharField, ChoiceField, EmailField, Field, Form, ModelChoiceField, ModelMultipleChoiceField, ) __all__ = [ "Field", "CharField", "ChoiceField", "EmailField", "BooleanField", "ModelMultipleChoiceField", "ModelChoiceField", ] class Input(Form): pass django-allauth-65.0.2/allauth/headless/internal/restkit/response.py000066400000000000000000000035521467545753200254600ustar00rootroot00000000000000from typing import Any, Dict, Optional from django.forms.utils import ErrorList from django.http import JsonResponse from django.utils.cache import add_never_cache_headers from allauth.headless.internal import authkit, sessionkit class APIResponse(JsonResponse): def __init__( self, request, errors=None, data=None, meta: Optional[Dict] = None, status: int = 200, ): d: Dict[str, Any] = {"status": status} if data is not None: d["data"] = data meta = self._add_session_meta(request, meta) if meta is not None: d["meta"] = meta if errors: d["errors"] = errors super().__init__(d, status=status) add_never_cache_headers(self) def _add_session_meta(self, request, meta: Optional[Dict]) -> Optional[Dict]: session_token = sessionkit.expose_session_token(request) access_token_payload = authkit.expose_access_token(request) if session_token: meta = meta or {} meta["session_token"] = session_token if access_token_payload: meta = meta or {} meta.update(access_token_payload) return meta class ErrorResponse(APIResponse): def __init__(self, request, exception=None, input=None, status=400): errors = [] if exception is not None: error_datas = ErrorList(exception.error_list).get_json_data() errors.extend(error_datas) if input is not None: for field, error_list in input.errors.items(): error_datas = error_list.get_json_data() for error_data in error_datas: if field != "__all__": error_data["param"] = field errors.extend(error_datas) super().__init__(request, status=status, errors=errors) django-allauth-65.0.2/allauth/headless/internal/restkit/views.py000066400000000000000000000035331467545753200247560ustar00rootroot00000000000000import json from typing import Dict, Optional, Type, Union from django.http import HttpResponseBadRequest from django.views.generic import View from allauth.core.exceptions import ImmediateHttpResponse from allauth.headless.internal.restkit.inputs import Input from allauth.headless.internal.restkit.response import ErrorResponse class RESTView(View): input_class: Union[Optional[Dict[str, Type[Input]]], Type[Input]] = None handle_json_input = True def dispatch(self, request, *args, **kwargs): return self.handle(request, *args, **kwargs) def handle(self, request, *args, **kwargs): if self.handle_json_input and request.method != "GET": self.data = self._parse_json(request) response = self.handle_input(self.data) if response: return response return super().dispatch(request, *args, **kwargs) def get_input_kwargs(self): return {} def handle_input(self, data): input_class = self.input_class if isinstance(input_class, dict): input_class = input_class.get(self.request.method) if not input_class: return input_kwargs = self.get_input_kwargs() if data is None: # Make form bound on empty POST data = {} self.input = input_class(data=data, **input_kwargs) if not self.input.is_valid(): return self.handle_invalid_input(self.input) def handle_invalid_input(self, input): return ErrorResponse(self.request, input=input) def _parse_json(self, request): if request.method == "GET" or not request.body: return try: return json.loads(request.body.decode("utf8")) except (UnicodeDecodeError, json.JSONDecodeError): raise ImmediateHttpResponse(response=HttpResponseBadRequest()) django-allauth-65.0.2/allauth/headless/internal/sessionkit.py000066400000000000000000000014451467545753200243270ustar00rootroot00000000000000from importlib import import_module from django.conf import settings from allauth.headless import app_settings from allauth.headless.constants import Client def session_store(session_key=None): engine = import_module(settings.SESSION_ENGINE) return engine.SessionStore(session_key=session_key) def new_session(): return session_store() def expose_session_token(request): if request.allauth.headless.client != Client.APP: return strategy = app_settings.TOKEN_STRATEGY hdr_token = strategy.get_session_token(request) modified = request.session.modified empty = request.session.is_empty() if modified and not empty: new_token = strategy.create_session_token(request) if not hdr_token or hdr_token != new_token: return new_token django-allauth-65.0.2/allauth/headless/internal/tests/000077500000000000000000000000001467545753200227205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/internal/tests/__init__.py000066400000000000000000000000001467545753200250170ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/internal/tests/test_authkit.py000066400000000000000000000017321467545753200260050ustar00rootroot00000000000000from django.contrib.auth import ( BACKEND_SESSION_KEY, HASH_SESSION_KEY, SESSION_KEY, ) from django.contrib.auth.middleware import AuthenticationMiddleware from django.contrib.sessions.middleware import SessionMiddleware from django.http import HttpResponse from allauth.headless.internal.authkit import purge_request_user_cache def test_purge_request_user_cache(rf, user): request = rf.get("/") smw = SessionMiddleware(lambda request: HttpResponse()) smw(request) amw = AuthenticationMiddleware(lambda request: HttpResponse()) amw(request) assert request.user.is_anonymous assert not request.user.pk purge_request_user_cache(request) request.session[SESSION_KEY] = user.pk request.session[BACKEND_SESSION_KEY] = ( "allauth.account.auth_backends.AuthenticationBackend" ) request.session[HASH_SESSION_KEY] = user.get_session_auth_hash() assert request.user.is_authenticated assert request.user.pk == user.pk django-allauth-65.0.2/allauth/headless/mfa/000077500000000000000000000000001467545753200205055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/mfa/__init__.py000066400000000000000000000000001467545753200226040ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/mfa/inputs.py000066400000000000000000000037461467545753200224130ustar00rootroot00000000000000from allauth.account.forms import BaseSignupForm from allauth.headless.internal.restkit import inputs from allauth.mfa.base.forms import AuthenticateForm from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.forms import GenerateRecoveryCodesForm from allauth.mfa.totp.forms import ActivateTOTPForm from allauth.mfa.webauthn.forms import ( AddWebAuthnForm, AuthenticateWebAuthnForm, LoginWebAuthnForm, ReauthenticateWebAuthnForm, SignupWebAuthnForm, ) class AuthenticateInput(AuthenticateForm, inputs.Input): pass class ActivateTOTPInput(ActivateTOTPForm, inputs.Input): pass class GenerateRecoveryCodesInput(GenerateRecoveryCodesForm, inputs.Input): pass class AddWebAuthnInput(AddWebAuthnForm, inputs.Input): pass class CreateWebAuthnInput(SignupWebAuthnForm, inputs.Input): pass class UpdateWebAuthnInput(inputs.Input): id = inputs.ModelChoiceField(queryset=Authenticator.objects.none()) name = inputs.CharField(required=True, max_length=100) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) self.fields["id"].queryset = Authenticator.objects.filter( user=self.user, type=Authenticator.Type.WEBAUTHN ) class DeleteWebAuthnInput(inputs.Input): authenticators = inputs.ModelMultipleChoiceField( queryset=Authenticator.objects.none() ) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) self.fields["authenticators"].queryset = Authenticator.objects.filter( user=self.user, type=Authenticator.Type.WEBAUTHN ) class ReauthenticateWebAuthnInput(ReauthenticateWebAuthnForm, inputs.Input): pass class AuthenticateWebAuthnInput(AuthenticateWebAuthnForm, inputs.Input): pass class LoginWebAuthnInput(LoginWebAuthnForm, inputs.Input): pass class SignupWebAuthnInput(BaseSignupForm, inputs.Input): pass django-allauth-65.0.2/allauth/headless/mfa/response.py000066400000000000000000000061341467545753200227210ustar00rootroot00000000000000from allauth.headless.base.response import APIResponse from allauth.mfa import app_settings as mfa_settings def get_config_data(request): data = { "mfa": { "supported_types": mfa_settings.SUPPORTED_TYPES, "passkey_login_enabled": mfa_settings.PASSKEY_LOGIN_ENABLED, } } return data def _authenticator_data(authenticator, sensitive=False): data = { "type": authenticator.type, "created_at": authenticator.created_at.timestamp(), "last_used_at": ( authenticator.last_used_at.timestamp() if authenticator.last_used_at else None ), } if authenticator.type == authenticator.Type.TOTP: pass elif authenticator.type == authenticator.Type.RECOVERY_CODES: wrapped = authenticator.wrap() unused_codes = wrapped.get_unused_codes() data.update( { "total_code_count": len(wrapped.generate_codes()), "unused_code_count": len(unused_codes), } ) if sensitive: data["unused_codes"] = unused_codes elif authenticator.type == authenticator.Type.WEBAUTHN: wrapped = authenticator.wrap() data["id"] = authenticator.pk data["name"] = wrapped.name passwordless = wrapped.is_passwordless if passwordless is not None: data["is_passwordless"] = passwordless return data class AuthenticatorDeletedResponse(APIResponse): pass class AuthenticatorsDeletedResponse(APIResponse): pass class TOTPNotFoundResponse(APIResponse): def __init__(self, request, secret, totp_url): super().__init__( request, meta={ "secret": secret, "totp_url": totp_url, }, status=404, ) class TOTPResponse(APIResponse): def __init__(self, request, authenticator): data = _authenticator_data(authenticator) super().__init__(request, data=data) class AuthenticatorsResponse(APIResponse): def __init__(self, request, authenticators): data = [_authenticator_data(authenticator) for authenticator in authenticators] super().__init__(request, data=data) class AuthenticatorResponse(APIResponse): def __init__(self, request, authenticator, meta=None): data = _authenticator_data(authenticator) super().__init__(request, data=data, meta=meta) class RecoveryCodesNotFoundResponse(APIResponse): def __init__(self, request): super().__init__(request, status=404) class RecoveryCodesResponse(APIResponse): def __init__(self, request, authenticator): data = _authenticator_data(authenticator, sensitive=True) super().__init__(request, data=data) class AddWebAuthnResponse(APIResponse): def __init__(self, request, registration_data): super().__init__(request, data={"creation_options": registration_data}) class WebAuthnRequestOptionsResponse(APIResponse): def __init__(self, request, request_options): super().__init__(request, data={"request_options": request_options}) django-allauth-65.0.2/allauth/headless/mfa/tests/000077500000000000000000000000001467545753200216475ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/mfa/tests/__init__.py000066400000000000000000000000001467545753200237460ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/mfa/tests/test_recovery_codes.py000066400000000000000000000037571467545753200263070ustar00rootroot00000000000000from allauth.mfa.models import Authenticator def test_get_recovery_codes_requires_reauth( auth_client, user_with_recovery_codes, headless_reverse ): rc = Authenticator.objects.get( type=Authenticator.Type.RECOVERY_CODES, user=user_with_recovery_codes ) resp = auth_client.get(headless_reverse("headless:mfa:manage_recovery_codes")) assert resp.status_code == 401 data = resp.json() assert data["meta"]["is_authenticated"] resp = auth_client.post( headless_reverse("headless:mfa:reauthenticate"), data={"code": rc.wrap().get_unused_codes()[0]}, content_type="application/json", ) assert resp.status_code == 200 def test_get_recovery_codes( auth_client, user_with_recovery_codes, headless_reverse, reauthentication_bypass, ): with reauthentication_bypass(): resp = auth_client.get(headless_reverse("headless:mfa:manage_recovery_codes")) assert resp.status_code == 200 data = resp.json() assert data["data"]["type"] == "recovery_codes" assert len(data["data"]["unused_codes"]) == 10 with reauthentication_bypass(): resp = auth_client.get(headless_reverse("headless:mfa:authenticators")) data = resp.json() assert len(data["data"]) == 2 rc = [autor for autor in data["data"] if autor["type"] == "recovery_codes"][0] assert "unused_codes" not in rc def test_generate_recovery_codes( auth_client, user_with_totp, headless_reverse, reauthentication_bypass, ): with reauthentication_bypass(): resp = auth_client.get(headless_reverse("headless:mfa:manage_recovery_codes")) assert resp.status_code == 404 with reauthentication_bypass(): resp = auth_client.post( headless_reverse("headless:mfa:manage_recovery_codes"), content_type="application/json", ) assert resp.status_code == 200 data = resp.json() assert data["data"]["type"] == "recovery_codes" assert len(data["data"]["unused_codes"]) == 10 django-allauth-65.0.2/allauth/headless/mfa/tests/test_totp.py000066400000000000000000000045421467545753200242530ustar00rootroot00000000000000import pytest from allauth.mfa.models import Authenticator @pytest.mark.parametrize("email_verified", [False, True]) def test_get_totp_not_active(auth_client, user, headless_reverse, email_verified): resp = auth_client.get(headless_reverse("headless:mfa:manage_totp")) if email_verified: assert resp.status_code == 404 data = resp.json() assert len(data["meta"]["secret"]) == 32 assert len(data["meta"]["totp_url"]) == 145 else: assert resp.status_code == 409 assert resp.json() == { "status": 409, "errors": [ { "message": "You cannot activate two-factor authentication until you have verified your email address.", "code": "unverified_email", } ], } def test_get_totp( auth_client, user_with_totp, headless_reverse, ): resp = auth_client.get(headless_reverse("headless:mfa:manage_totp")) assert resp.status_code == 200 data = resp.json() assert data["data"]["type"] == "totp" assert isinstance(data["data"]["created_at"], float) def test_deactivate_totp( auth_client, user_with_totp, headless_reverse, reauthentication_bypass, ): with reauthentication_bypass(): resp = auth_client.delete(headless_reverse("headless:mfa:manage_totp")) assert resp.status_code == 200 assert not Authenticator.objects.filter(user=user_with_totp).exists() @pytest.mark.parametrize("email_verified", [False, True]) def test_activate_totp( auth_client, user, headless_reverse, reauthentication_bypass, settings, totp_validation_bypass, email_verified, ): with reauthentication_bypass(): with totp_validation_bypass(): resp = auth_client.post( headless_reverse("headless:mfa:manage_totp"), data={"code": "42"}, content_type="application/json", ) if email_verified: assert resp.status_code == 200 assert Authenticator.objects.filter( user=user, type=Authenticator.Type.TOTP ).exists() data = resp.json() assert data["data"]["type"] == "totp" assert isinstance(data["data"]["created_at"], float) assert data["data"]["last_used_at"] is None else: assert resp.status_code == 400 django-allauth-65.0.2/allauth/headless/mfa/tests/test_views.py000066400000000000000000000066231467545753200244240ustar00rootroot00000000000000from allauth.account.models import EmailAddress, get_emailconfirmation_model from allauth.headless.constants import Flow def test_auth_unverified_email_and_mfa( client, user_factory, password_factory, settings, totp_validation_bypass, headless_reverse, headless_client, ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" password = password_factory() user = user_factory(email_verified=False, password=password, with_totp=True) resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": password, }, content_type="application/json", ) assert resp.status_code == 401 data = resp.json() assert [f for f in data["data"]["flows"] if f["id"] == Flow.VERIFY_EMAIL][0][ "is_pending" ] emailaddress = EmailAddress.objects.filter(user=user, verified=False).get() key = get_emailconfirmation_model().create(emailaddress).key resp = client.post( headless_reverse("headless:account:verify_email"), data={"key": key}, content_type="application/json", ) assert resp.status_code == 401 flows = [ {"id": "login"}, {"id": "login_by_code"}, {"id": "signup"}, ] if headless_client == "browser": flows.append( { "id": "provider_redirect", "providers": ["dummy", "openid_connect", "openid_connect"], } ) flows.append({"id": "provider_token", "providers": ["dummy"]}) flows.append({"id": "mfa_login_webauthn"}) flows.append( { "id": "mfa_authenticate", "is_pending": True, "types": ["totp"], } ) assert resp.json() == { "data": {"flows": flows}, "meta": {"is_authenticated": False}, "status": 401, } resp = client.post( headless_reverse("headless:mfa:authenticate"), data={"code": "bad"}, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ {"message": "Incorrect code.", "code": "incorrect_code", "param": "code"} ], } with totp_validation_bypass(): resp = client.post( headless_reverse("headless:mfa:authenticate"), data={"code": "bad"}, content_type="application/json", ) assert resp.status_code == 200 def test_dangling_mfa_is_logged_out( client, user_with_totp, password_factory, settings, totp_validation_bypass, headless_reverse, headless_client, user_password, ): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" resp = client.post( headless_reverse("headless:account:login"), data={ "email": user_with_totp.email, "password": user_password, }, content_type="application/json", ) assert resp.status_code == 401 data = resp.json() flow = [f for f in data["data"]["flows"] if f["id"] == Flow.MFA_AUTHENTICATE][0] assert flow["is_pending"] assert flow["types"] == ["totp"] resp = client.delete(headless_reverse("headless:account:current_session")) data = resp.json() assert resp.status_code == 401 assert all(not f.get("is_pending") for f in data["data"]["flows"]) django-allauth-65.0.2/allauth/headless/mfa/tests/test_webauthn.py000066400000000000000000000171071467545753200251030ustar00rootroot00000000000000from unittest.mock import ANY from django.contrib.auth import get_user_model import pytest from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.headless.constants import Flow from allauth.mfa.models import Authenticator def test_passkey_login( client, passkey, webauthn_authentication_bypass, headless_reverse ): with webauthn_authentication_bypass(passkey) as credential: resp = client.get(headless_reverse("headless:mfa:login_webauthn")) assert "request_options" in resp.json()["data"] resp = client.post( headless_reverse("headless:mfa:login_webauthn"), data={"credential": credential}, content_type="application/json", ) data = resp.json() assert data["data"]["user"]["id"] == passkey.user_id def test_passkey_login_get_options(client, headless_client, headless_reverse, db): resp = client.get(headless_reverse("headless:mfa:login_webauthn")) data = resp.json() meta = {} if headless_client == "app": meta = { "meta": {"session_token": ANY}, } assert data == { "status": 200, "data": {"request_options": {"publicKey": ANY}}, **meta, } def test_reauthenticate( auth_client, passkey, user_with_recovery_codes, webauthn_authentication_bypass, headless_reverse, ): # View recovery codes, confirm webauthn reauthentication is an option resp = auth_client.get(headless_reverse("headless:mfa:manage_recovery_codes")) assert resp.status_code == 401 assert Flow.MFA_REAUTHENTICATE in [ flow["id"] for flow in resp.json()["data"]["flows"] ] # Get request options with webauthn_authentication_bypass(passkey): resp = auth_client.get(headless_reverse("headless:mfa:reauthenticate_webauthn")) data = resp.json() assert data["status"] == 200 assert data["data"]["request_options"] == ANY # Reauthenticate with webauthn_authentication_bypass(passkey) as credential: resp = auth_client.post( headless_reverse("headless:mfa:reauthenticate_webauthn"), data={"credential": credential}, content_type="application/json", ) assert resp.status_code == 200 resp = auth_client.get(headless_reverse("headless:mfa:manage_recovery_codes")) assert resp.status_code == 200 def test_update_authenticator( auth_client, headless_reverse, passkey, reauthentication_bypass ): data = {"id": passkey.pk, "name": "Renamed!"} resp = auth_client.put( headless_reverse("headless:mfa:manage_webauthn"), data=data, content_type="application/json", ) # Reauthentication required assert resp.status_code == 401 with reauthentication_bypass(): resp = auth_client.put( headless_reverse("headless:mfa:manage_webauthn"), data=data, content_type="application/json", ) assert resp.status_code == 200 passkey.refresh_from_db() assert passkey.wrap().name == "Renamed!" def test_delete_authenticator( auth_client, headless_reverse, passkey, reauthentication_bypass ): data = {"authenticators": [passkey.pk]} resp = auth_client.delete( headless_reverse("headless:mfa:manage_webauthn"), data=data, content_type="application/json", ) # Reauthentication required assert resp.status_code == 401 with reauthentication_bypass(): resp = auth_client.delete( headless_reverse("headless:mfa:manage_webauthn"), data=data, content_type="application/json", ) assert resp.status_code == 200 assert not Authenticator.objects.filter(pk=passkey.pk).exists() @pytest.mark.parametrize("email_verified", [False, True]) def test_add_authenticator( user, auth_client, headless_reverse, webauthn_registration_bypass, reauthentication_bypass, email_verified, ): resp = auth_client.get(headless_reverse("headless:mfa:manage_webauthn")) # Reauthentication required assert resp.status_code == 401 if email_verified else 409 with reauthentication_bypass(): resp = auth_client.get(headless_reverse("headless:mfa:manage_webauthn")) if email_verified: assert resp.status_code == 200 data = resp.json() assert data["data"]["creation_options"] == ANY else: assert resp.status_code == 409 with webauthn_registration_bypass(user, False) as credential: resp = auth_client.post( headless_reverse("headless:mfa:manage_webauthn"), data={"credential": credential}, content_type="application/json", ) webauthn_count = Authenticator.objects.filter( type=Authenticator.Type.WEBAUTHN, user=user ).count() if email_verified: assert resp.status_code == 200 assert webauthn_count == 1 else: assert resp.status_code == 409 assert webauthn_count == 0 def test_2fa_login( client, user, user_password, passkey, webauthn_authentication_bypass, headless_reverse, ): resp = client.post( headless_reverse("headless:account:login"), data={ "username": user.username, "password": user_password, }, content_type="application/json", ) assert resp.status_code == 401 data = resp.json() pending_flows = [f for f in data["data"]["flows"] if f.get("is_pending")] assert len(pending_flows) == 1 pending_flow = pending_flows[0] assert pending_flow == { "id": "mfa_authenticate", "is_pending": True, "types": ["webauthn"], } with webauthn_authentication_bypass(passkey) as credential: resp = client.get(headless_reverse("headless:mfa:authenticate_webauthn")) assert "request_options" in resp.json()["data"] resp = client.post( headless_reverse("headless:mfa:authenticate_webauthn"), data={"credential": credential}, content_type="application/json", ) data = resp.json() assert resp.status_code == 200 assert data["data"]["user"]["id"] == passkey.user_id assert client.headless_session()[AUTHENTICATION_METHODS_SESSION_KEY] == [ {"method": "password", "at": ANY, "username": passkey.user.username}, {"method": "mfa", "at": ANY, "id": ANY, "type": Authenticator.Type.WEBAUTHN}, ] def test_passkey_signup(client, db, webauthn_registration_bypass, headless_reverse): resp = client.post( headless_reverse("headless:mfa:signup_webauthn"), data={"email": "pass@key.org", "username": "passkey"}, content_type="application/json", ) assert resp.status_code == 401 flow = [flow for flow in resp.json()["data"]["flows"] if flow.get("is_pending")][0] assert flow["id"] == Flow.MFA_SIGNUP_WEBAUTHN.value resp = client.get(headless_reverse("headless:mfa:signup_webauthn")) data = resp.json() assert "creation_options" in data["data"] user = get_user_model().objects.get(email="pass@key.org") with webauthn_registration_bypass(user, True) as credential: resp = client.put( headless_reverse("headless:mfa:signup_webauthn"), data={"name": "Some key", "credential": credential}, content_type="application/json", ) data = resp.json() assert data["meta"]["is_authenticated"] authenticator = Authenticator.objects.get(user=user) assert authenticator.wrap().name == "Some key" django-allauth-65.0.2/allauth/headless/mfa/urls.py000066400000000000000000000057271467545753200220570ustar00rootroot00000000000000from django.urls import include, path from allauth.headless.mfa import views from allauth.mfa import app_settings as mfa_settings def build_urlpatterns(client): auth_patterns = [ path( "2fa/authenticate", views.AuthenticateView.as_api_view(client=client), name="authenticate", ), path( "2fa/reauthenticate", views.ReauthenticateView.as_api_view(client=client), name="reauthenticate", ), ] authenticators = [] if "totp" in mfa_settings.SUPPORTED_TYPES: authenticators.append( path( "totp", views.ManageTOTPView.as_api_view(client=client), name="manage_totp", ) ) if "recovery_codes" in mfa_settings.SUPPORTED_TYPES: authenticators.append( path( "recovery-codes", views.ManageRecoveryCodesView.as_api_view(client=client), name="manage_recovery_codes", ) ) if "webauthn" in mfa_settings.SUPPORTED_TYPES: authenticators.extend( [ path( "webauthn", views.ManageWebAuthnView.as_api_view(client=client), name="manage_webauthn", ), ] ) auth_patterns.extend( [ path( "webauthn/authenticate", views.AuthenticateWebAuthnView.as_api_view(client=client), name="authenticate_webauthn", ), path( "webauthn/reauthenticate", views.ReauthenticateWebAuthnView.as_api_view(client=client), name="reauthenticate_webauthn", ), ] ) if mfa_settings.PASSKEY_LOGIN_ENABLED: auth_patterns.append( path( "webauthn/login", views.LoginWebAuthnView.as_api_view(client=client), name="login_webauthn", ) ) if mfa_settings.PASSKEY_SIGNUP_ENABLED: auth_patterns.append( path( "webauthn/signup", views.SignupWebAuthnView.as_api_view(client=client), name="signup_webauthn", ) ) return [ path( "auth/", include(auth_patterns), ), path( "account/", include( [ path( "authenticators", views.AuthenticatorsView.as_api_view(client=client), name="authenticators", ), path( "authenticators/", include(authenticators), ), ] ), ), ] django-allauth-65.0.2/allauth/headless/mfa/views.py000066400000000000000000000226521467545753200222230ustar00rootroot00000000000000from django.core.exceptions import ValidationError from allauth.account.internal.stagekit import get_pending_stage from allauth.account.models import Login from allauth.headless.account.views import SignupView from allauth.headless.base.response import ( APIResponse, AuthenticationResponse, ConflictResponse, ) from allauth.headless.base.views import ( APIView, AuthenticatedAPIView, AuthenticationStageAPIView, ) from allauth.headless.internal.restkit.response import ErrorResponse from allauth.headless.mfa import response from allauth.headless.mfa.inputs import ( ActivateTOTPInput, AddWebAuthnInput, AuthenticateInput, AuthenticateWebAuthnInput, CreateWebAuthnInput, DeleteWebAuthnInput, GenerateRecoveryCodesInput, LoginWebAuthnInput, ReauthenticateWebAuthnInput, SignupWebAuthnInput, UpdateWebAuthnInput, ) from allauth.mfa.adapter import DefaultMFAAdapter, get_adapter from allauth.mfa.internal.flows import add from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.internal import flows as recovery_codes_flows from allauth.mfa.stages import AuthenticateStage from allauth.mfa.totp.internal import auth as totp_auth, flows as totp_flows from allauth.mfa.webauthn.internal import ( auth as webauthn_auth, flows as webauthn_flows, ) from allauth.mfa.webauthn.stages import PasskeySignupStage def _validate_can_add_authenticator(request): try: add.validate_can_add_authenticator(request.user) except ValidationError as e: return ErrorResponse(request, status=409, exception=e) class AuthenticateView(AuthenticationStageAPIView): input_class = AuthenticateInput stage_class = AuthenticateStage def post(self, request, *args, **kwargs): self.input.save() return self.respond_next_stage() def get_input_kwargs(self): return {"user": self.stage.login.user} class ReauthenticateView(AuthenticatedAPIView): input_class = AuthenticateInput def post(self, request, *args, **kwargs): self.input.save() return AuthenticationResponse(self.request) def get_input_kwargs(self): return {"user": self.request.user} class AuthenticatorsView(AuthenticatedAPIView): def get(self, request, *args, **kwargs): authenticators = Authenticator.objects.filter(user=request.user) return response.AuthenticatorsResponse(request, authenticators) class ManageTOTPView(AuthenticatedAPIView): input_class = {"POST": ActivateTOTPInput} def get(self, request, *args, **kwargs) -> APIResponse: authenticator = self._get_authenticator() if not authenticator: err = _validate_can_add_authenticator(request) if err: return err adapter: DefaultMFAAdapter = get_adapter() secret = totp_auth.get_totp_secret(regenerate=True) totp_url: str = adapter.build_totp_url(request.user, secret) return response.TOTPNotFoundResponse(request, secret, totp_url) return response.TOTPResponse(request, authenticator) def _get_authenticator(self): return Authenticator.objects.filter( type=Authenticator.Type.TOTP, user=self.request.user ).first() def get_input_kwargs(self): return {"user": self.request.user} def post(self, request, *args, **kwargs): authenticator = totp_flows.activate_totp(request, self.input)[0] return response.TOTPResponse(request, authenticator) def delete(self, request, *args, **kwargs): authenticator = self._get_authenticator() if authenticator: authenticator = totp_flows.deactivate_totp(request, authenticator) return response.AuthenticatorDeletedResponse(request) class ManageRecoveryCodesView(AuthenticatedAPIView): input_class = GenerateRecoveryCodesInput def get(self, request, *args, **kwargs): authenticator = recovery_codes_flows.view_recovery_codes(request) if not authenticator: return response.RecoveryCodesNotFoundResponse(request) return response.RecoveryCodesResponse(request, authenticator) def post(self, request, *args, **kwargs): authenticator = recovery_codes_flows.generate_recovery_codes(request) return response.RecoveryCodesResponse(request, authenticator) def get_input_kwargs(self): return {"user": self.request.user} class ManageWebAuthnView(AuthenticatedAPIView): input_class = { "POST": AddWebAuthnInput, "PUT": UpdateWebAuthnInput, "DELETE": DeleteWebAuthnInput, } def handle(self, request, *args, **kwargs): if request.method in ["GET", "POST"]: err = _validate_can_add_authenticator(request) if err: return err return super().handle(request, *args, **kwargs) def get(self, request, *args, **kwargs): passwordless = "passwordless" in request.GET creation_options = webauthn_flows.begin_registration( request, request.user, passwordless ) return response.AddWebAuthnResponse(request, creation_options) def get_input_kwargs(self): return {"user": self.request.user} def post(self, request, *args, **kwargs): auth, rc_auth = webauthn_flows.add_authenticator( request, name=self.input.cleaned_data["name"], credential=self.input.cleaned_data["credential"], ) did_generate_recovery_codes = bool(rc_auth) return response.AuthenticatorResponse( request, auth, meta={"recovery_codes_generated": did_generate_recovery_codes}, ) def put(self, request, *args, **kwargs): authenticator = self.input.cleaned_data["id"] webauthn_flows.rename_authenticator( request, authenticator, self.input.cleaned_data["name"] ) return response.AuthenticatorResponse(request, authenticator) def delete(self, request, *args, **kwargs): authenticators = self.input.cleaned_data["authenticators"] webauthn_flows.remove_authenticators(request, authenticators) return response.AuthenticatorsDeletedResponse(request) class ReauthenticateWebAuthnView(AuthenticatedAPIView): input_class = { "POST": ReauthenticateWebAuthnInput, } def get(self, request, *args, **kwargs): request_options = webauthn_auth.begin_authentication(request.user) return response.WebAuthnRequestOptionsResponse(request, request_options) def get_input_kwargs(self): return {"user": self.request.user} def post(self, request, *args, **kwargs): authenticator = self.input.cleaned_data["credential"] webauthn_flows.reauthenticate(request, authenticator) return AuthenticationResponse(self.request) class AuthenticateWebAuthnView(AuthenticationStageAPIView): input_class = { "POST": AuthenticateWebAuthnInput, } stage_class = AuthenticateStage def get(self, request, *args, **kwargs): request_options = webauthn_auth.begin_authentication(self.stage.login.user) return response.WebAuthnRequestOptionsResponse(request, request_options) def get_input_kwargs(self): return {"user": self.stage.login.user} def post(self, request, *args, **kwargs): self.input.save() return self.respond_next_stage() class LoginWebAuthnView(APIView): input_class = { "POST": LoginWebAuthnInput, } def get(self, request, *args, **kwargs): request_options = webauthn_auth.begin_authentication() return response.WebAuthnRequestOptionsResponse(request, request_options) def post(self, request, *args, **kwargs): authenticator = self.input.cleaned_data["credential"] redirect_url = None login = Login(user=authenticator.user, redirect_url=redirect_url) webauthn_flows.perform_passwordless_login(request, authenticator, login) return AuthenticationResponse(request) class SignupWebAuthnView(SignupView): input_class = { "POST": SignupWebAuthnInput, "PUT": CreateWebAuthnInput, } by_passkey = True def get(self, request, *args, **kwargs): resp = self._require_stage() if resp: return resp creation_options = webauthn_flows.begin_registration( request, self.stage.login.user, passwordless=True, signup=True ) return response.AddWebAuthnResponse(request, creation_options) def _prep_stage(self): if hasattr(self, "stage"): return self.stage self.stage = get_pending_stage(self.request) return self.stage def _require_stage(self): self._prep_stage() if not self.stage or self.stage.key != PasskeySignupStage.key: return ConflictResponse(self.request) return None def get_input_kwargs(self): ret = super().get_input_kwargs() self._prep_stage() if self.stage and self.request.method == "PUT": ret["user"] = self.stage.login.user return ret def put(self, request, *args, **kwargs): resp = self._require_stage() if resp: return resp webauthn_flows.signup_authenticator( request, user=self.stage.login.user, name=self.input.cleaned_data["name"], credential=self.input.cleaned_data["credential"], ) self.stage.exit() return AuthenticationResponse(request) django-allauth-65.0.2/allauth/headless/socialaccount/000077500000000000000000000000001467545753200225715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/socialaccount/__init__.py000066400000000000000000000000001467545753200246700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/socialaccount/forms.py000066400000000000000000000020571467545753200242750ustar00rootroot00000000000000from django import forms from allauth.account.adapter import get_adapter as get_account_adapter from allauth.core import context from allauth.headless.adapter import get_adapter from allauth.socialaccount.adapter import ( get_adapter as get_socialaccount_adapter, ) from allauth.socialaccount.providers.base.constants import AuthProcess class RedirectToProviderForm(forms.Form): provider = forms.CharField() callback_url = forms.CharField() process = forms.ChoiceField( choices=[ (AuthProcess.LOGIN, AuthProcess.LOGIN), (AuthProcess.CONNECT, AuthProcess.CONNECT), ] ) def clean_callback_url(self): url = self.cleaned_data["callback_url"] if not get_account_adapter().is_safe_url(url): raise get_adapter().validation_error("invalid_url") return url def clean_provider(self): provider_id = self.cleaned_data["provider"] provider = get_socialaccount_adapter().get_provider( context.request, provider_id ) return provider django-allauth-65.0.2/allauth/headless/socialaccount/inputs.py000066400000000000000000000111101467545753200244570ustar00rootroot00000000000000from django.core.exceptions import ValidationError from allauth.core import context from allauth.headless.adapter import get_adapter from allauth.headless.internal.restkit import inputs from allauth.socialaccount.adapter import ( get_adapter as get_socialaccount_adapter, ) from allauth.socialaccount.forms import SignupForm from allauth.socialaccount.models import SocialAccount, SocialApp from allauth.socialaccount.providers import registry from allauth.socialaccount.providers.base.constants import AuthProcess class SignupInput(SignupForm, inputs.Input): pass class DeleteProviderAccountInput(inputs.Input): provider = inputs.CharField() account = inputs.CharField() def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) def clean(self): cleaned_data = super().clean() uid = cleaned_data.get("account") provider_id = cleaned_data.get("provider") if uid and provider_id: accounts = SocialAccount.objects.filter(user=self.user) account = accounts.filter( uid=uid, provider=provider_id, ).first() if not account: raise get_adapter().validation_error("account_not_found") get_socialaccount_adapter().validate_disconnect(account, accounts) self.cleaned_data["account"] = account return cleaned_data class ProviderTokenInput(inputs.Input): provider = inputs.CharField() process = inputs.ChoiceField( choices=[ (AuthProcess.LOGIN, AuthProcess.LOGIN), (AuthProcess.CONNECT, AuthProcess.CONNECT), ] ) token = inputs.Field() def clean(self): cleaned_data = super().clean() token = self.data.get("token") adapter = get_adapter() if not isinstance(token, dict): self.add_error("token", adapter.validation_error("invalid_token")) token = None provider_id = cleaned_data.get("provider") provider = None if provider_id and token: provider_class = registry.get_class(provider_id) # If `provider_id` is a sub provider ID we won't find it by class. client_id_required = provider_class is None or provider_class.uses_apps client_id = token.get("client_id") if client_id_required and not isinstance(client_id, str): self.add_error("token", adapter.validation_error("client_id_required")) else: try: provider = get_socialaccount_adapter().get_provider( context.request, provider_id, client_id=client_id ) except SocialApp.DoesNotExist: self.add_error("token", adapter.validation_error("invalid_token")) else: if not provider.supports_token_authentication: self.add_error( "provider", adapter.validation_error( "token_authentication_not_supported" ), ) elif ( provider.uses_apps and client_id and provider.app.client_id != client_id ): self.add_error( "token", adapter.validation_error("client_id_mismatch") ) else: id_token = token.get("id_token") access_token = token.get("access_token") if ( (id_token is not None and not isinstance(id_token, str)) or ( access_token is not None and not isinstance(access_token, str) ) or (not id_token and not access_token) ): self.add_error( "token", adapter.validation_error("token_required") ) if not self.errors: cleaned_data["provider"] = provider try: login = provider.verify_token(context.request, token) login.state["process"] = cleaned_data["process"] cleaned_data["sociallogin"] = login except ValidationError as e: self.add_error("token", e) return cleaned_data django-allauth-65.0.2/allauth/headless/socialaccount/internal.py000066400000000000000000000060321467545753200247600ustar00rootroot00000000000000from django.core.exceptions import PermissionDenied, ValidationError from django.http import HttpResponseRedirect from allauth import app_settings as allauth_settings from allauth.core.exceptions import ( ImmediateHttpResponse, SignupClosedException, ) from allauth.core.internal import httpkit from allauth.headless.internal.authkit import AuthenticationStatus from allauth.socialaccount.internal import flows, statekit from allauth.socialaccount.providers.base.constants import ( AuthError, AuthProcess, ) def on_authentication_error( request, provider, error=None, exception=None, extra_context=None, state_id=None, ): """ Called at a time when it is not clear whether or not this is a headless flow. """ state = None if extra_context: state = extra_context.get("state") if state is None: state_id = extra_context.get("state_id") if state_id: state = statekit.unstash_state(request, state_id) params = {"error": error} if state is not None: headless = state.get("headless") next_url = state.get("next") params["error_process"] = state["process"] else: headless = allauth_settings.HEADLESS_ONLY next_url = None params["error_process"] = AuthProcess.LOGIN if not headless: return if not next_url: next_url = httpkit.get_frontend_url(request, "socialaccount_login_error") or "/" next_url = httpkit.add_query_params(next_url, params) raise ImmediateHttpResponse(HttpResponseRedirect(next_url)) def complete_token_login(request, sociallogin): flows.login.complete_login(request, sociallogin, raises=True) def complete_login(request, sociallogin): """ Called when `sociallogin.is_headless`. """ error = None try: flows.login.complete_login(request, sociallogin, raises=True) except SignupClosedException: error = "signup_closed" except PermissionDenied: error = "permission_denied" except ValidationError as e: error = e.code else: # At this stage, we're either: # 1) logged in (or in of the login pipeline stages, such as email verification) # 2) auto signed up -- a pipeline stage, so see 1) # 3) performing a social signup # 4) Stopped, due to not being open-for-signup # It would be good to refactor the above into a more generic social login # pipeline with clear stages, but for now the /auth endpoint properly responds status = AuthenticationStatus(request) if all( [ not status.is_authenticated, not status.has_pending_signup, not status.get_pending_stage(), ] ): error = AuthError.UNKNOWN next_url = sociallogin.state["next"] if error: next_url = httpkit.add_query_params( next_url, {"error": error, "error_process": sociallogin.state["process"]}, ) return HttpResponseRedirect(next_url) django-allauth-65.0.2/allauth/headless/socialaccount/response.py000066400000000000000000000060511467545753200250030ustar00rootroot00000000000000from allauth.headless.base.response import APIResponse from allauth.headless.constants import Client, Flow from allauth.socialaccount.adapter import ( get_adapter as get_socialaccount_adapter, ) from allauth.socialaccount.internal.flows import signup from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider def _provider_data(request, provider): ret = {"id": provider.sub_id, "name": provider.name, "flows": []} if provider.supports_redirect: ret["flows"].append(Flow.PROVIDER_REDIRECT) if provider.supports_token_authentication: ret["flows"].append(Flow.PROVIDER_TOKEN) if isinstance(provider, OAuth2Provider): ret["client_id"] = provider.app.client_id return ret def provider_flows(request): flows = [] providers = _list_supported_providers(request) if providers: redirect_providers = [p.id for p in providers if p.supports_redirect] token_providers = [p.id for p in providers if p.supports_token_authentication] if redirect_providers and request.allauth.headless.client == Client.BROWSER: flows.append( { "id": Flow.PROVIDER_REDIRECT, "providers": redirect_providers, } ) if token_providers: flows.append( { "id": Flow.PROVIDER_TOKEN, "providers": token_providers, } ) sociallogin = signup.get_pending_signup(request) if sociallogin: flows.append(_signup_flow(request, sociallogin)) return flows def _signup_flow(request, sociallogin): provider = sociallogin.account.get_provider() flow = { "id": Flow.PROVIDER_SIGNUP, "provider": _provider_data(request, provider), "is_pending": True, } return flow def _is_provider_supported(provider, client): if client == Client.APP: return provider.supports_token_authentication elif client == Client.BROWSER: return provider.supports_redirect return False def _list_supported_providers(request): adapter = get_socialaccount_adapter() providers = adapter.list_providers(request) providers = [ p for p in providers if _is_provider_supported(p, request.allauth.headless.client) ] return providers def get_config_data(request): entries = [] data = {"socialaccount": {"providers": entries}} providers = _list_supported_providers(request) providers = sorted(providers, key=lambda p: p.name) for provider in providers: entries.append(_provider_data(request, provider)) return data class SocialAccountsResponse(APIResponse): def __init__(self, request, accounts): data = [ { "uid": account.uid, "provider": _provider_data(request, account.get_provider()), "display": account.get_provider_account().to_str(), } for account in accounts ] super().__init__(request, data=data) django-allauth-65.0.2/allauth/headless/socialaccount/tests/000077500000000000000000000000001467545753200237335ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/socialaccount/tests/__init__.py000066400000000000000000000000001467545753200260320ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/socialaccount/tests/test_inputs.py000066400000000000000000000021641467545753200266710ustar00rootroot00000000000000import pytest from allauth.headless.socialaccount.inputs import ProviderTokenInput @pytest.mark.parametrize("client_id", ["client1", "client2"]) def test_provider_token_multiple_apps(settings, db, client_id): gsettings = { "APPS": [ {"client_id": "client1", "secret": "secret"}, {"client_id": "client2", "secret": "secret"}, ] } settings.SOCIALACCOUNT_PROVIDERS = {"google": gsettings} inp = ProviderTokenInput( { "provider": "google", "process": "login", "token": {"client_id": client_id, "id_token": "it", "access_token": "at"}, } ) assert not inp.is_valid() assert inp.cleaned_data["provider"].app.client_id == client_id assert inp.errors == {"token": ["Invalid token."]} def test_provider_token_client_id_required(settings, db): inp = ProviderTokenInput( { "provider": "google", "process": "login", "token": {"id_token": "it", "access_token": "at"}, } ) assert not inp.is_valid() assert inp.errors == {"token": ["`client_id` required."]} django-allauth-65.0.2/allauth/headless/socialaccount/tests/test_views.py000066400000000000000000000310341467545753200265020ustar00rootroot00000000000000import json from unittest.mock import patch from django.urls import reverse from pytest_django.asserts import assertTemplateUsed from allauth.account.models import EmailAddress from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.base.constants import AuthProcess def test_bad_redirect(client, headless_reverse, db, settings): settings.HEADLESS_ONLY = False resp = client.post( headless_reverse("headless:socialaccount:redirect_to_provider"), data={ "provider": "dummy", "callback_url": "https://unsafe.org/hack", "process": AuthProcess.LOGIN, }, ) assertTemplateUsed(resp, "socialaccount/authentication_error.html") def test_valid_redirect(client, headless_reverse, db): resp = client.post( headless_reverse("headless:socialaccount:redirect_to_provider"), data={ "provider": "dummy", "callback_url": "/", "process": AuthProcess.LOGIN, }, ) assert resp.status_code == 302 def test_manage_providers(auth_client, user, headless_reverse, provider_id): account_to_del = SocialAccount.objects.create( user=user, provider=provider_id, uid="p123" ) account_to_keep = SocialAccount.objects.create( user=user, provider=provider_id, uid="p456" ) resp = auth_client.get( headless_reverse("headless:socialaccount:manage_providers"), ) data = resp.json() assert data["status"] == 200 assert len(data["data"]) == 2 resp = auth_client.delete( headless_reverse("headless:socialaccount:manage_providers"), data={"provider": account_to_del.provider, "account": account_to_del.uid}, content_type="application/json", ) assert resp.status_code == 200 assert resp.json() == { "status": 200, "data": [ { "display": "Unittest Server", "provider": { "client_id": "Unittest client_id", "flows": ["provider_redirect"], "id": provider_id, "name": "Unittest Server", }, "uid": "p456", } ], } assert not SocialAccount.objects.filter(pk=account_to_del.pk).exists() assert SocialAccount.objects.filter(pk=account_to_keep.pk).exists() def test_disconnect_bad_request(auth_client, user, headless_reverse, provider_id): resp = auth_client.delete( headless_reverse("headless:socialaccount:manage_providers"), data={"provider": provider_id, "account": "unknown"}, content_type="application/json", ) assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [{"code": "account_not_found", "message": "Unknown account."}], } def test_valid_token(client, headless_reverse, db): id_token = json.dumps( { "id": 123, "email": "a@b.com", "email_verified": True, } ) resp = client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "dummy", "token": { "id_token": id_token, }, "process": AuthProcess.LOGIN, }, content_type="application/json", ) assert resp.status_code == 200 assert EmailAddress.objects.filter(email="a@b.com", verified=True).exists() def test_invalid_token(client, headless_reverse, db, google_provider_settings): resp = client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "google", "token": { "id_token": "dummy", "client_id": google_provider_settings["APPS"][0]["client_id"], }, "process": AuthProcess.LOGIN, }, content_type="application/json", ) assert resp.status_code == 400 data = resp.json() assert data == { "status": 400, "errors": [ {"message": "Invalid token.", "code": "invalid_token", "param": "token"} ], } def test_auth_error_no_headless_request(client, db, google_provider_settings, settings): """Authentication errors use the regular "Third-Party Login Failure" template if headless is not used. """ settings.HEADLESS_ONLY = False resp = client.get(reverse("google_callback")) assertTemplateUsed(resp, "socialaccount/authentication_error.html") def test_auth_error_headless_request( client, db, google_provider_settings, sociallogin_setup_state ): """Authentication errors redirect to the next URL with ?error params for headless requests. """ state = sociallogin_setup_state(client, headless=True, next="/foo") resp = client.get(reverse("google_callback") + f"?state={state}") assert resp["location"] == "/foo?error=unknown&error_process=login" def test_auth_error_no_headless_state_request_headless_only( settings, client, db, google_provider_settings ): """Authentication errors redirect to a fallback error URL for headless-only, in case no next can be recovered from the state. """ settings.HEADLESS_ONLY = True settings.HEADLESS_FRONTEND_URLS = {"socialaccount_login_error": "/3rdparty/failure"} resp = client.get(reverse("google_callback")) assert ( resp["location"] == "http://testserver/3rdparty/failure?error=unknown&error_process=login" ) def test_auth_error_headless_state_request_headless_only( settings, client, db, google_provider_settings, sociallogin_setup_state ): """Authentication errors redirect to a fallback error URL for headless-only, in case no next can be recovered from the state. """ state = sociallogin_setup_state(client, headless=True, next="/foo") settings.HEADLESS_ONLY = True settings.HEADLESS_FRONTEND_URLS = {"socialaccount_login_error": "/3rdparty/failure"} resp = client.get(reverse("google_callback") + f"?state={state}") assert resp["location"] == "/foo?error=unknown&error_process=login" def test_token_signup_closed(client, headless_reverse, db): id_token = json.dumps( { "id": 123, "email": "a@b.com", "email_verified": True, } ) with patch( "allauth.socialaccount.adapter.DefaultSocialAccountAdapter.is_open_for_signup" ) as iofs: iofs.return_value = False resp = client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "dummy", "token": { "id_token": id_token, }, "process": AuthProcess.LOGIN, }, content_type="application/json", ) assert resp.status_code == 403 assert not EmailAddress.objects.filter(email="a@b.com", verified=True).exists() def test_provider_signup(client, headless_reverse, db, settings): settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_USERNAME_REQUIRED = False id_token = json.dumps( { "id": 123, } ) resp = client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "dummy", "token": { "id_token": id_token, }, "process": AuthProcess.LOGIN, }, content_type="application/json", ) assert resp.status_code == 401 pending_flow = [f for f in resp.json()["data"]["flows"] if f.get("is_pending")][0] assert pending_flow["id"] == "provider_signup" resp = client.post( headless_reverse("headless:socialaccount:provider_signup"), data={ "email": "a@b.com", }, content_type="application/json", ) assert resp.status_code == 401 pending_flow = [f for f in resp.json()["data"]["flows"] if f.get("is_pending")][0] assert pending_flow["id"] == "verify_email" assert EmailAddress.objects.filter(email="a@b.com").exists() def test_signup_closed(client, headless_reverse, db, settings): settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_USERNAME_REQUIRED = False id_token = json.dumps( { "id": 123, } ) resp = client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "dummy", "token": { "id_token": id_token, }, "process": AuthProcess.LOGIN, }, content_type="application/json", ) assert resp.status_code == 401 pending_flow = [f for f in resp.json()["data"]["flows"] if f.get("is_pending")][0] assert pending_flow["id"] == "provider_signup" with patch( "allauth.socialaccount.adapter.DefaultSocialAccountAdapter.is_open_for_signup" ) as iofs: iofs.return_value = False resp = client.post( headless_reverse("headless:socialaccount:provider_signup"), data={ "email": "a@b.com", }, content_type="application/json", ) assert resp.status_code == 403 def test_connect(user, auth_client, sociallogin_setup_state, headless_reverse, db): state = sociallogin_setup_state( auth_client, process="connect", next="/foo", headless=True ) resp = auth_client.post( reverse("dummy_authenticate") + f"?state={state}", data={ "id": 123, }, ) assert resp.status_code == 302 assert resp["location"] == "/foo" assert SocialAccount.objects.filter(user=user, provider="dummy", uid="123").exists() def test_connect_already_connected( user, user_factory, auth_client, sociallogin_setup_state, headless_reverse, db ): # The other user already connected the account. other_user = user_factory() SocialAccount.objects.create(user=other_user, uid="123", provider="dummy") # Then, this user tries to connect... state = sociallogin_setup_state( auth_client, process=AuthProcess.CONNECT, next="/foo", headless=True ) resp = auth_client.post( reverse("dummy_authenticate") + f"?state={state}", data={ "id": 123, }, ) # We're redirected, and an error code is shown. assert resp.status_code == 302 assert resp["location"] == "/foo?error=connected_other&error_process=connect" assert not SocialAccount.objects.filter( user=user, provider="dummy", uid="123" ).exists() def test_token_connect(user, auth_client, headless_reverse, db): id_token = json.dumps( { "id": 123, "email": "a@b.com", "email_verified": True, } ) resp = auth_client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "dummy", "token": { "id_token": id_token, }, "process": AuthProcess.CONNECT, }, content_type="application/json", ) assert resp.status_code == 200 assert SocialAccount.objects.filter(uid="123", user=user).exists() def test_token_connect_already_connected( user, auth_client, headless_reverse, db, user_factory ): # The other user already connected the account. other_user = user_factory() SocialAccount.objects.create(user=other_user, uid="123", provider="dummy") id_token = json.dumps( { "id": 123, "email": "a@b.com", "email_verified": True, } ) resp = auth_client.post( headless_reverse("headless:socialaccount:provider_token"), data={ "provider": "dummy", "token": { "id_token": id_token, }, "process": AuthProcess.CONNECT, }, content_type="application/json", ) assert not SocialAccount.objects.filter(uid="123", user=user).exists() assert resp.status_code == 400 assert resp.json() == { "status": 400, "errors": [ { "code": "connected_other", "message": "The third-party account is already connected to a different account.", } ], } def test_provider_signup_not_pending(client, headless_reverse, db, settings): resp = client.post( headless_reverse("headless:socialaccount:provider_signup"), data={ "email": "a@b.com", }, content_type="application/json", ) assert resp.status_code == 409 django-allauth-65.0.2/allauth/headless/socialaccount/urls.py000066400000000000000000000032271467545753200241340ustar00rootroot00000000000000from django.urls import include, path from allauth.headless.socialaccount import views def build_urlpatterns(client): return [ path( "account/", include( [ path( "providers", views.ManageProvidersView.as_api_view(client=client), name="manage_providers", ), ] ), ), path( "auth/", include( [ path( "provider/", include( [ path( "signup", views.ProviderSignupView.as_api_view(client=client), name="provider_signup", ), path( "redirect", views.RedirectToProviderView.as_api_view( client=client ), name="redirect_to_provider", ), path( "token", views.ProviderTokenView.as_api_view(client=client), name="provider_token", ), ] ), ) ] ), ), ] django-allauth-65.0.2/allauth/headless/socialaccount/views.py000066400000000000000000000067651467545753200243160ustar00rootroot00000000000000from django.core.exceptions import ValidationError from allauth.core.exceptions import SignupClosedException from allauth.headless.base.response import ( AuthenticationResponse, ConflictResponse, ForbiddenResponse, ) from allauth.headless.base.views import APIView, AuthenticatedAPIView from allauth.headless.internal.restkit.response import ErrorResponse from allauth.headless.socialaccount.forms import RedirectToProviderForm from allauth.headless.socialaccount.inputs import ( DeleteProviderAccountInput, ProviderTokenInput, SignupInput, ) from allauth.headless.socialaccount.internal import complete_token_login from allauth.headless.socialaccount.response import SocialAccountsResponse from allauth.socialaccount.adapter import ( get_adapter as get_socialaccount_adapter, ) from allauth.socialaccount.helpers import render_authentication_error from allauth.socialaccount.internal import flows from allauth.socialaccount.models import SocialAccount class ProviderSignupView(APIView): input_class = SignupInput def handle(self, request, *args, **kwargs): self.sociallogin = flows.signup.get_pending_signup(self.request) if not self.sociallogin: return ConflictResponse(request) if not get_socialaccount_adapter().is_open_for_signup( request, self.sociallogin ): return ForbiddenResponse(request) return super().handle(request, *args, **kwargs) def post(self, request, *args, **kwargs): flows.signup.signup_by_form(self.request, self.sociallogin, self.input) return AuthenticationResponse(request) def get_input_kwargs(self): return {"sociallogin": self.sociallogin} class RedirectToProviderView(APIView): handle_json_input = False def post(self, request, *args, **kwargs): form = RedirectToProviderForm(request.POST) if not form.is_valid(): return render_authentication_error( request, provider=request.POST.get("provider"), exception=ValidationError(form.errors), ) provider = form.cleaned_data["provider"] next_url = form.cleaned_data["callback_url"] process = form.cleaned_data["process"] return provider.redirect( request, process, next_url=next_url, headless=True, ) class ManageProvidersView(AuthenticatedAPIView): input_class = { "DELETE": DeleteProviderAccountInput, } def get(self, request, *args, **kwargs): return self.respond_provider_accounts(request) @classmethod def respond_provider_accounts(self, request): accounts = SocialAccount.objects.filter(user=request.user) return SocialAccountsResponse(request, accounts) def delete(self, request, *args, **kwargs): flows.connect.disconnect(request, self.input.cleaned_data["account"]) return self.respond_provider_accounts(request) def get_input_kwargs(self): return {"user": self.request.user} class ProviderTokenView(APIView): input_class = ProviderTokenInput def post(self, request, *args, **kwargs): sociallogin = self.input.cleaned_data["sociallogin"] try: complete_token_login(request, sociallogin) except ValidationError as e: return ErrorResponse(self.request, exception=e) except SignupClosedException: return ForbiddenResponse(self.request) return AuthenticationResponse(self.request) django-allauth-65.0.2/allauth/headless/tests/000077500000000000000000000000001467545753200211045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/tests/__init__.py000066400000000000000000000000001467545753200232030ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/tests/test_tokens.py000066400000000000000000000016011467545753200240160ustar00rootroot00000000000000from allauth.headless.tokens.sessions import SessionTokenStrategy class DummyAccessTokenStrategy(SessionTokenStrategy): def create_access_token(self, request): return f"at-user-{request.user.pk}" def test_access_token( client, user, user_password, settings, headless_reverse, headless_client, ): settings.HEADLESS_TOKEN_STRATEGY = ( "allauth.headless.tests.test_tokens.DummyAccessTokenStrategy" ) resp = client.post( headless_reverse("headless:account:login"), data={ "username": user.username, "password": user_password, }, content_type="application/json", ) data = resp.json() assert data["status"] == 200 if headless_client == "app": assert data["meta"]["access_token"] == f"at-user-{user.pk}" else: assert "access_token" not in data["meta"] django-allauth-65.0.2/allauth/headless/tokens/000077500000000000000000000000001467545753200212455ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/tokens/__init__.py000066400000000000000000000000001467545753200233440ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/tokens/base.py000066400000000000000000000040511467545753200225310ustar00rootroot00000000000000import abc from typing import Any, Dict, Optional from django.contrib.sessions.backends.base import SessionBase from django.http import HttpRequest class AbstractTokenStrategy(abc.ABC): def get_session_token(self, request: HttpRequest) -> Optional[str]: """ Returns the session token, if any. """ token = request.headers.get("x-session-token") return token def create_access_token_payload( self, request: HttpRequest ) -> Optional[Dict[str, Any]]: """ After authenticating, this method is called to create the access token response payload, exposing the access token and possibly other information such as a ``refresh_token`` and ``expires_in``. """ at = self.create_access_token(request) if not at: return None return {"access_token": at} def create_access_token(self, request: HttpRequest) -> Optional[str]: """Create an access token. While session tokens are required to handle the authentication process, depending on your requirements, a different type of token may be needed once authenticated. For example, your app likely needs access to other APIs as well. These APIs may even be implemented using different technologies, in which case having a stateless token, possibly a JWT encoding the user ID, might be a good fit. We make no assumptions in this regard. If you need access tokens, you will have to implement a token strategy that returns an access token here. """ return None @abc.abstractmethod def create_session_token(self, request: HttpRequest) -> str: """ Create a session token for the `request.session`. """ ... @abc.abstractmethod def lookup_session(self, session_token: str) -> Optional[SessionBase]: """ Looks up the Django session given the session token. Returns `None` if the session does not / no longer exist. """ ... django-allauth-65.0.2/allauth/headless/tokens/sessions.py000066400000000000000000000014271467545753200234710ustar00rootroot00000000000000import typing from django.contrib.sessions.backends.base import SessionBase from django.http import HttpRequest from allauth.headless.internal import sessionkit from allauth.headless.tokens.base import AbstractTokenStrategy class SessionTokenStrategy(AbstractTokenStrategy): def create_session_token(self, request: HttpRequest) -> str: if not request.session.session_key: request.session.save() key = request.session.session_key assert isinstance(key, str) # We did save. return key def lookup_session(self, session_token: str) -> typing.Optional[SessionBase]: session_key = session_token if sessionkit.session_store().exists(session_key): return sessionkit.session_store(session_key) return None django-allauth-65.0.2/allauth/headless/urls.py000066400000000000000000000037471467545753200213140ustar00rootroot00000000000000from django.urls import include, path from allauth import app_settings as allauth_settings from allauth.headless.account import urls as account_urls from allauth.headless.base import urls as base_urls from allauth.headless.constants import Client def build_urlpatterns(client): patterns = [] patterns.extend(base_urls.build_urlpatterns(client)) patterns.append( path( "", include( (account_urls.build_urlpatterns(client), "headless"), namespace="account", ), ) ) if allauth_settings.SOCIALACCOUNT_ENABLED: from allauth.headless.socialaccount import urls as socialaccount_urls patterns.append( path( "", include( (socialaccount_urls.build_urlpatterns(client), "headless"), namespace="socialaccount", ), ) ) if allauth_settings.MFA_ENABLED: from allauth.headless.mfa import urls as mfa_urls patterns.append( path( "", include( (mfa_urls.build_urlpatterns(client), "headless"), namespace="mfa", ), ) ) if allauth_settings.USERSESSIONS_ENABLED: from allauth.headless.usersessions import urls as usersessions_urls patterns.append( path( "", include( (usersessions_urls.build_urlpatterns(client), "headless"), namespace="usersessions", ), ) ) return [path("v1/", include(patterns))] app_name = "headless" urlpatterns = [ path( "browser/", include( (build_urlpatterns(Client.BROWSER), "headless"), namespace="browser", ), ), path( "app/", include((build_urlpatterns(Client.APP), "headless"), namespace="app"), ), ] django-allauth-65.0.2/allauth/headless/usersessions/000077500000000000000000000000001467545753200225075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/usersessions/__init__.py000066400000000000000000000000001467545753200246060ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/usersessions/inputs.py000066400000000000000000000006711467545753200244070ustar00rootroot00000000000000from allauth.headless.internal.restkit import inputs from allauth.usersessions.models import UserSession class SelectSessionsInput(inputs.Input): sessions = inputs.ModelMultipleChoiceField(queryset=UserSession.objects.none()) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) self.fields["sessions"].queryset = UserSession.objects.filter(user=self.user) django-allauth-65.0.2/allauth/headless/usersessions/response.py000066400000000000000000000014341467545753200247210ustar00rootroot00000000000000from allauth.headless.base.response import APIResponse from allauth.usersessions import app_settings class SessionsResponse(APIResponse): def __init__(self, request, sessions): super().__init__(request, data=[self._session_data(s) for s in sessions]) def _session_data(self, session): data = { "user_agent": session.user_agent, "ip": session.ip, "created_at": session.created_at.timestamp(), "is_current": session.is_current(), "id": session.pk, } if app_settings.TRACK_ACTIVITY: data["last_seen_at"] = session.last_seen_at.timestamp() return data def get_config_data(request): data = {"usersessions": {"track_activity": app_settings.TRACK_ACTIVITY}} return data django-allauth-65.0.2/allauth/headless/usersessions/tests/000077500000000000000000000000001467545753200236515ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/usersessions/tests/__init__.py000066400000000000000000000000001467545753200257500ustar00rootroot00000000000000django-allauth-65.0.2/allauth/headless/usersessions/tests/test_views.py000066400000000000000000000017211467545753200264200ustar00rootroot00000000000000from allauth.usersessions.models import UserSession def test_flow(client, user, user_password, headless_reverse, settings): settings.ACCOUNT_AUTHENTICATION_METHOD = "email" resp = client.post( headless_reverse("headless:account:login"), data={ "email": user.email, "password": user_password, }, content_type="application/json", ) assert resp.status_code == 200 resp = client.get(headless_reverse("headless:usersessions:sessions")) assert resp.status_code == 200 data = resp.json() assert len(data["data"]) == 1 session_pk = data["data"][0]["id"] assert UserSession.objects.filter(pk=session_pk).exists() resp = client.delete( headless_reverse("headless:usersessions:sessions"), data={"sessions": [session_pk]}, content_type="application/json", ) assert resp.status_code == 401 assert not UserSession.objects.filter(pk=session_pk).exists() django-allauth-65.0.2/allauth/headless/usersessions/urls.py000066400000000000000000000007051467545753200240500ustar00rootroot00000000000000from django.urls import include, path from allauth.headless.usersessions import views def build_urlpatterns(client): return [ path( "auth/", include( [ path( "sessions", views.SessionsView.as_api_view(client=client), name="sessions", ), ] ), ) ] django-allauth-65.0.2/allauth/headless/usersessions/views.py000066400000000000000000000021041467545753200242130ustar00rootroot00000000000000from allauth.headless.base.response import AuthenticationResponse from allauth.headless.base.views import AuthenticatedAPIView from allauth.headless.usersessions.inputs import SelectSessionsInput from allauth.headless.usersessions.response import SessionsResponse from allauth.usersessions.internal import flows from allauth.usersessions.models import UserSession class SessionsView(AuthenticatedAPIView): input_class = {"DELETE": SelectSessionsInput} def delete(self, request, *args, **kwargs): sessions = self.input.cleaned_data["sessions"] flows.sessions.end_sessions(request, sessions) if self.request.user.is_authenticated: return self._respond_session_list() return AuthenticationResponse(request) def get(self, request, *args, **kwargs): return self._respond_session_list() def _respond_session_list(self): sessions = UserSession.objects.purge_and_list(self.request.user) return SessionsResponse(self.request, sessions) def get_input_kwargs(self): return {"user": self.request.user} django-allauth-65.0.2/allauth/locale/000077500000000000000000000000001467545753200174115ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ar/000077500000000000000000000000001467545753200200135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ar/LC_MESSAGES/000077500000000000000000000000001467545753200216005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ar/LC_MESSAGES/django.po000066400000000000000000001727371467545753200234230ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-07-08 18:09+0000\n" "Last-Translator: Amr Essam \n" "Language-Team: Arabic \n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" "X-Generator: Weblate 5.7-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "هذا الحساب غير نشط حاليا." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "لا يمكنك إزالة عنوان البريد الإلكتروني الرئيسي (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "عنوان البريد الإلكتروني هذا مربوط بالفعل مع هذا الحساب." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "عنوان البريد الإلكتروني و / أو كلمة المرور غير صحيحة." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "هنالك مستخدم مسجل سابقا يستخدم عنوان البريد الإلكتروني نفسه." #: account/adapter.py:62 msgid "Please type your current password." msgstr "الرجاء كتابة كلمة المرور الحالية." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "شفرة خاطئة." #: account/adapter.py:64 msgid "Incorrect password." msgstr "كلمة مرور خاطئة." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "مفتاح خاطئ او منتهي." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "كود إعادة تعيين كلمة المرور غير صالح." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "لا يمكنك إضافة أكثر من %d بريد إلكتروني." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "تجاوزت الحد المسموح لمحاولة تسجيل الدخول. حاول في وقت لاحق." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "لم يتم ربط عنوان البريد الإلكتروني مع أي حساب مستخدم" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "يجب توثيق عنوان بريدك الإلكتروني الرئيسي." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "اسم المستخدم غير مسموح به. الرجاء اختيار اسم آخر‪." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "اسم المستخدم و / أو كلمة المرور غير صحيحة." #: account/adapter.py:741 msgid "Use your password" msgstr "استخدم كلمة مرورك" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "استخدم تطبيق المصادقة او الكود" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "مفتاح سري" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "تحديد البريد الإلكتروني المختار بأنه تم التحقق منه" #: account/apps.py:11 msgid "Accounts" msgstr "الحسابات" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "يجب عليك كتابة كلمة المرور نفسها في كل مرة‪." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "كلمة المرور" #: account/forms.py:93 msgid "Remember Me" msgstr "تذكرني" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "عنوان البريد الالكتروني" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "البريد الالكتروني" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "اسم المستخدم" #: account/forms.py:123 msgid "Username or email" msgstr "اسم المستخدم أو البريد الإلكتروني" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "تسجيل الدخول" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "هل نسيت كلمة المرور؟" #: account/forms.py:299 msgid "Email (again)" msgstr "البريد الإلكتروني ‪(مجددا)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "تأكيد البريد الإلكتروني" #: account/forms.py:311 msgid "Email (optional)" msgstr "البريد الالكتروني (اختياري)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "يجب عليك كتابة البريد الإلكتروني نفسه في كل مرة‪." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "كلمة المرور (مجددا)" #: account/forms.py:554 msgid "Current Password" msgstr "كلمة المرور الحالية" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "كلمة المرور الجديدة" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "كلمة المرور الجديدة (مجددا)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "شفرة" #: account/models.py:26 msgid "user" msgstr "مستخدم" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "عنوان بريد إلكتروني" #: account/models.py:34 msgid "verified" msgstr "موثق" #: account/models.py:35 msgid "primary" msgstr "رئيسي" #: account/models.py:41 msgid "email addresses" msgstr "عناوين البريد الالكتروني" #: account/models.py:150 msgid "created" msgstr "تمّ إنشاؤه" #: account/models.py:151 msgid "sent" msgstr "تم ارساله" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "مفتاح" #: account/models.py:157 msgid "email confirmation" msgstr "تأكيد البريد الإلكتروني" #: account/models.py:158 msgid "email confirmations" msgstr "تأكيدات البريد الإلكتروني" #: headless/apps.py:7 msgid "Headless" msgstr "مقطوعة الرأس" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "لا يمكنك إضافة عنوان بريد إلكتروني إلى حساب محمي بواسطة المصادقة الثنائية." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "لا يمكنك إلغاء تنشيط المصادقة الثنائية." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "لا يمكنك إنشاء رموز الاسترداد دون تمكين المصادقة الثنائية." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "لا يمكنك تفعيل المصادقة الثنائية إلا بعد التحقق من عنوان بريدك الإلكتروني." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "مفتاح سري" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "وزارة الخارجية" #: mfa/models.py:24 msgid "Recovery codes" msgstr "رموز الاسترداد" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "أداة مصادقة TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "كود المصدق" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "كلمة المرور" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "يوجد حساب بالفعل مربوط مع هذا البريد الإلكتروني. يرجى الدخول إلى ذاك الحساب " "أولا، ثم ربط حسابك في %s." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "كود غير صالح" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "حسابك ليست له كلمة مرور مضبوطة." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "حسابك ليس لديه عنوان بريد إلكتروني موثقف." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "يمكنك تسجيل الدخول إلى حسابك باستخدام أي من حسابات الطرف الثالث التالية:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "حساب التواصل الاجتماعي متصل مسبقا مع حساب مختلف." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "حسابات التواصل الاجتماعي" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "مزود" #: socialaccount/models.py:52 msgid "provider ID" msgstr "معرف المزود" #: socialaccount/models.py:56 msgid "name" msgstr "اسم" #: socialaccount/models.py:58 msgid "client id" msgstr "معرف العميل" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "معرف آبل، أو مفتاح المستهلك" #: socialaccount/models.py:63 msgid "secret key" msgstr "مفتاح سري" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "مفتاح واجهة برمجية سري أو مفتاح مستهلك" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "مفتاح" #: socialaccount/models.py:81 msgid "social application" msgstr "تطبيق اجتماعي" #: socialaccount/models.py:82 msgid "social applications" msgstr "تطبيقات اجتماعية" #: socialaccount/models.py:117 msgid "uid" msgstr "معرف المستخدم" #: socialaccount/models.py:119 msgid "last login" msgstr "أخر دخول" #: socialaccount/models.py:120 msgid "date joined" msgstr "تاريخ الانضمام" #: socialaccount/models.py:121 msgid "extra data" msgstr "بيانات إضافية" #: socialaccount/models.py:125 msgid "social account" msgstr "حساب تواصل اجتماعي" #: socialaccount/models.py:126 msgid "social accounts" msgstr "حسابات تواصل اجتماعي" #: socialaccount/models.py:160 msgid "token" msgstr "كود" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) أو مفتاح وصول (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "كود سري" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) أو رمز تحديث (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "ينتهي في" #: socialaccount/models.py:174 msgid "social application token" msgstr "كود تطبيق اجتماعي" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "أكواد التطبيقات الاجتماعية" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "معلومات ملف شخصي غير صالحة" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "تسجيل الدخول" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "يلغي" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "تم تلقي رد غير صالح عند الحصول على كود الطلب من \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "تم تلقي رد غير صالح عند الحصول على كود الوصول من \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "لا يوجد كود طلب محفوظ لـ \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "لا يوجد كود وصول محفوظ لـ \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "لا وصول للموارد الخاصة في \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "تم تلقي رد غير صالح عند الحصول على كود الطلب من \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "الحساب غير نشط" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "هذا الحساب غير نشط." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "تأكيد البريد الإلكتروني" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "يرجى إعادة المصادقة لحماية حسابك." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "خيارات بديلة" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "تأكيد البريد الإلكتروني" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "كود سري" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "لقد أرسلنا رمزًا إلى %(email_link)s. الرمز ينتهي قريبًا، لذا يرجى إدخاله قريبًا." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "تأكيد" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "تسجيل الدخول" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "أدخل رمز تسجيل الدخول" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "عناوين البريد الإلكتروني" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "عناوين البريد الإلكتروني التالية مربوطة مع حسابك:" #: templates/account/email.html:25 msgid "Verified" msgstr "موثق" #: templates/account/email.html:29 msgid "Unverified" msgstr "غير موثق" #: templates/account/email.html:34 msgid "Primary" msgstr "أساسي" #: templates/account/email.html:44 msgid "Make Primary" msgstr "اجعله أساسيا" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "إعادة ارسال رسالة التأكيد" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "احذف" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "أضف عنوان بريد إلكتروني" #: templates/account/email.html:70 msgid "Add Email" msgstr "أضف بريدا إلكترونيا" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "هل تريد حقا حذف عنوان البريد الإلكتروني المحدد؟" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "تلقيت هذه الرسالة لأنك أو أحد آخر حاول تسجيل حساب\n" "باستخدام البريد الإلكتروني:\n" "\n" "%(email)s\n" "\n" "لكن حسابا مربوطا بهذا البريد موجود بالفعل. في حال نسيت هذا، يمكنك استخدام " "رابط\n" "إعادة ضبط كلمة المرور لاستعادة حسابك:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "الحساب موجود بالفعل" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "مرحبا من موقع %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "شكرا لاستخدامك %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "أنت تتلقى هذا البريد لأنه تم إجراء التغيير التالي على حسابك:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "0 إذا لم تتعرف على هذا التغيير، فيرجى اتخاذ الاحتياطات الأمنية المناسبة على " "الفور. ينشأ التغيير في حسابك من:.\n" "- عنوان IP: %(ip)s.\n" "- المتصفح: %(user_agent)s.\n" "- التاريخ: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "J لقد تم تغيير بريدك الإلكتروني من %(from_email)s إلى %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "عنوان البريد الالكتروني" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your email has been confirmed." msgstr "تم حذف كلمة المرور الخاصة بك." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "تأكيد البريد الإلكتروني" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "تلقيت هذه الرسالة لأن المستخدم %(user_display)s أعطانا بريدك الإلكتروني " "لتسجيل حساب في %(site_domain)s.\n" "\n" "لتأكيد هذا، يرجى الذهاب إلى %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "رمز تسجيل الدخول الخاص بك مدرج أدناه. الرجاء إدخاله في نافذة المتصفح " "المفتوحة." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "أكد عنوان البريد الإلكتروني" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "تمت إزالة عنوان البريد الإلكتروني %(deleted_email)s من حسابك." #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "احذف" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "رمز تسجيل الدخول الخاص بك مدرج أدناه. الرجاء إدخاله في نافذة المتصفح " "المفتوحة." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "يمكن تجاهل هذا البريد بأمان إذا لم تبدأ هذا الإجراء." #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "تسجيل الدخول" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "تم تغيير كلمة المرور الخاصة بك." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "كلمة المرور (مجددا)" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "تلقيت هذه الرسالة لأنك أو أحد آخر طلب إعادة ضبط كلمة مرور حسابك.\n" "يمكنك تجاهل الرسالة بأمان إذا لم تطلب هذا. اضغط الرابط في الأسفل لإعادة ضبط " "كلمة المرور." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "في حال كنت قد نسيت، اسم المستخدم الخاص بك هو %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "رسالة إعادة ضبط كلمة المرور" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been reset." msgstr "تم حذف كلمة المرور الخاصة بك." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "إعادة تعيين كلمة المرور" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been set." msgstr "تم حذف كلمة المرور الخاصة بك." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "إعادة تعيين كلمة المرور" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "O أنت تتلقى هذا البريد الإلكتروني لأنك، أو حاول شخص آخر، الوصول إلى حساب " "باستخدام البريد الإلكتروني %(email)s. ومع ذلك، ليس لدينا أي سجل لمثل هذا " "الحساب في قاعدة بياناتنا." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "إذا كنت أنت، فيمكنك التسجيل للحصول على حساب باستخدام الرابط أدناه." #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "حساب" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "بريد إلكتروني" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "كلمة المرور الحالية" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "التغيير إلى" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your email address is still pending verification:" msgid "Your email address is still pending verification." msgstr "ما زال عنوان البريد الإلكتروني بانتظار التوثيق:" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "إلغاء التغيير" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Change Email" msgid "Change to" msgstr "تغيير البريد الإلكتروني" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "تغيير البريد الإلكتروني" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "تأكيد البريد الإلكتروني" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "يرجى تأكيد أن %(email)s هو عنوان بريد " "إلكتروني للمستخدم %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "فشل تأكيد %(email)s لأنه مؤكد بالفعل في حساب مختلف." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "هذا الرابط لتأكيد البريد الإلكتروني نتهت فترة صلاحيته أو إنه غير صالح. يرجى " "طلب رابط جديد لتأكيد البريد الإلكتروني." #: templates/account/login.html:19 #, fuzzy, python-format #| msgid "" #| "If you have not created an account yet, then please\n" #| "sign up first." msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "إذا لم يكن لديك حساب بالفعل،\n" "يرجى التسجيل أولا." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "أرسل لي رمز تسجيل الدخول" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "تسجيل الخروج" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "هل تريد حقا تسجيل الخروج؟" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "لا يمكنك إزالة عنوان البريد الإلكتروني الرئيسي (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "تم إرسال رسالة تأكيد إلى العنوان %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "لقد أكدت عنوان البريد الإلكتروني %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "تمت إزالة عنوان البريد الإلكتروني %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "لقد سجلت الدخول بنجاح يا %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "تم تسجيل خروجك." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "تم إرسال رمز تسجيل الدخول بالبريد إلى %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "تم تغيير كلمة المرور بنجاح‪." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "تم إعداد كلمة المرور بنجاح‪." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "تم تعيين عنوان البريد الإلكتروني الرئيسي‪." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "غيّر كلمة المرور" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "هل نسيت كلمة المرور؟" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "هل نسيت كلمة المرور؟ أدخل عنوان البريد الإلكتروني أدناه، وسنرسل لك رسالة " "تتيح لك إعادة تعيينها." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "إعادة تعيين كلمة المرور" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "يرجى الاتصال بنا إذا كنت تواجه أي مشاكل في إعادة تعيين كلمة المرور." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "أرسلنا لك رسالة. إذا لم تصلك يرجى التحقق من صندوق الرسائل غير المرغوب فيها. " "اتصل بنا إذا لم تصل في غضون دقائق." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "كود غير صالح" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "رابط إعادة تعيين كلمة المرور غير صالح، ربما لأنه قد تم استخدامه مسبقا. يرجى " "طلب رابط جديد." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "تم تغيير كلمة المرور الخاصة بك." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "تعيين كلمة مرور" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "هل نسيت كلمة المرور؟" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "ستتلقى بريدًا إلكترونيًا يحتوي على رمز خاص لتسجيل الدخول بدون كلمة مرور." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "كود الطلب" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "خيارات تسجيل الدخول الأخرى" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "التسجيل" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "الاشتراك" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "لديك حساب؟ %(link)sسجل الدخول%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "الاشتراك" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "خيارات تسجيل الدخول الأخرى" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "الاشتراك مغلق" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "نحن آسفون‪:‬ الاشتراك مغلق حاليا‪." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "ملاحظة" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "تم تسجيل دخولك بالفعل يا %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "تحذير‪:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "ليس لديك أي بريد إلكتروني مضبوط. عليك حقا إضافة عنوان لكي تتلقى الإشعارات، " "وتعيد تعيين كلمة المرور، إلخ." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "التحقق من البريد الإلكتروني" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "لقد أرسلنا لك رسالة للتوثيق. اتبع الرابط المزود لإكمال عملية التسجيل. إذا لم " "ترى الرسالة في صندوقك الرئيسي، تحقق من صندوق الرسائل غير المرغوب فيها. يرجى " "التواصل معنا إذا لم تتلقى الرسالة في غضو دقائق." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "تتطلب هذه الصفحة توثيق هويتك.\n" "لهذا نطلب منك توثيق ملكية بريدك الإلكتروني. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "أرسلنا لك رسالة للتوثيق.\n" "يرجى الضغط على الرابط في الرسالة. إذا لم ترى الرسالة في صندوقك الرئيسي، تحقق " "من صندوق الرسائل غير المرغوب فيها.\n" "يرجى التواصل معنا إذا لم تتلقاه في غضون دقائق." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "ملاحظة: ما زال بإمكانك تغيير " "البريد الإلكتروني." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "رسائل:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "قائمة:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "اتصالات الحساب" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "توثيق ذو عاملين" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "الجلسات" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "حسابك محمي بواسطة المصادقة الثنائية. الرجاء إدخال رمز المصادقة:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "تم إنشاء مجموعة جديدة من رموز استرداد المصادقة الثنائية." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "تم إنشاء رموز استرداد جديدة" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "تم تفعيل تطبيق المصادقة." #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "كود سري" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "تم تعطيل تطبيق المصادقة." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "تم تعطيل تطبيق المصادقة" #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "تم إنشاء مجموعة جديدة من رموز الاسترداد." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "A security key has been removed." msgstr "تم حذف كلمة المرور الخاصة بك." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "تطبيق المصادقة" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "المصادقة باستخدام تطبيق المصادقة نشطة." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "تطبيق المصادقة غير نشط." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "إلغاء التنشيط" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "تفعيل" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" msgstr[4] "" msgstr[5] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "رموز الاسترداد" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "هناك 6(unused_count)s من %(total_count)s رموز الاسترداد المتاحة." msgstr[1] "هناك 6(unused_count)s من %(total_count)s رموز الاسترداد المتاحة." msgstr[2] "هناك %(unused_count)s من %(total_count)s رموز الاسترداد المتاحة." msgstr[3] "هناك %(unused_count)s من %(total_count)s رموز الاسترداد المتاحة." msgstr[4] "هناك %(unused_count)s من %(total_count)s رموز الاسترداد المتاحة." msgstr[5] "هناك %(unused_count)s من %(total_count)s رموز الاسترداد المتاحة." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "لم يتم إعداد رموز الاسترداد." #: templates/mfa/index.html:96 msgid "View" msgstr "منظر" #: templates/mfa/index.html:102 msgid "Download" msgstr "تحميل" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "يولد" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "تم إنشاء مجموعة جديدة من رموز الاسترداد." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "كود سري" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "أنت على وشك إنشاء مجموعة جديدة من رموز الاسترداد لحسابك." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "سيؤدي هذا الإجراء إلى إبطال رموزك الحالية." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "هل أنت متأكد؟" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "رموز غير مستخدمة" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "تنزيل الرموز" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "توليد رموز جديدة" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "تفعيل تطبيق المصادقة" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "لحماية حسابك من خلال المصادقة الثنائية، قم بمسح رمز الاستجابة السريعة أدناه " "باستخدام تطبيق المصادقة الخاص بك. ثم أدخل رمز التحقق الذي أنشأه التطبيق " "أدناه." #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "كود سري" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "يمكنك تخزين هذا السر واستخدامه لإعادة تثبيت تطبيق المصادقة الخاص بك في وقت " "لاحق." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "قم بإلغاء تنشيط تطبيق المصادقة" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "أنت على وشك إلغاء تنشيط المصادقة المستندة إلى تطبيق المصادقة. هل أنت متأكد؟" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "مفتاح سري" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "مفتاح سري" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "هل تريد حقا تسجيل الخروج؟" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "مفتاح سري" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "غير موثق" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "مفتاح سري" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "كلمة المرور الحالية" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "تمّ إنشاؤه" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "فشل تسجيل الدخول الاجتماعي" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "حدث خطأ أثناء محاولة تسجيل الدخول عن طريق حساب الشبكة الاجتماعية." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "يمكنك تسجيل الدخول إلى حسابك باستخدام أي من حسابات الطرف الثالث التالية:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "ليس لديك حاليا أي شبكة اجتماعية متصلة بهذا الحساب." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "إضافة حساب طرف الثالث" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "تم ربط حساب جهة خارجية من %(provider)s بحسابك." #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "إضافة حساب طرف الثالث" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "تم قطع اتصال حساب جهة خارجية من %(provider)s بحسابك." #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "إضافة حساب طرف الثالث" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "ربط %(provider)s" #: templates/socialaccount/login.html:13 #, fuzzy, python-format #| msgid "" #| "You are about to connect a new third party account from %(provider)s." msgid "You are about to connect a new third-party account from %(provider)s." msgstr "أنت على وشك ربط حساب طرف ثالث جديد من %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "تسجيل الدخول عبر %(provider)s" #: templates/socialaccount/login.html:20 #, fuzzy, python-format #| msgid "" #| "You are about to sign in using a third party account from %(provider)s." msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "أنت على وشك تسجيل الدخول باستخدام حساب الطرف الثالث من %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "المتابعة" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "تم إلغاء تسجيل الدخول" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "قد قررت إلغاء تسجيل الدخول إلى الموقع باستخدام أحد الحسابات الموجودة الخاصة " "بك. إذا كان هذا خطأ، الرجاء المتابعة إلى تسجيل " "الدخول." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "تم ربط حساب التواصل الاجتماعي." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "تم قطع الاتصال بحساب التواصل الاجتماعي." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "أنت على وشك استخدام حسابك من %(provider_name)s لتسجيل الدخول إلى " "%(site_name)s.\n" "كخطوة أخيرة، يرجى ملء النموذج التالي:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "أو استخدم طرفًا ثالثًا" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "تم تسجيل الخروج من جميع الجلسات الأخرى." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "بدأت في" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Address" msgid "IP Address" msgstr "بريد إلكتروني" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "المتصفح" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "شوهد آخر مرة في" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "كلمة المرور الحالية" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "تسجيل الخروج من الجلسات الأخرى" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "جلسات المستخدم" #: usersessions/models.py:92 msgid "session key" msgstr "مفتاح جلسة" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "اتصالات الحساب" #~ msgid "Use security key or device" #~ msgstr "استخدم مفتاح او جهاز الحماية" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "كلمة المرور يجب أن لا تقل عن {0} حروف." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "تلقيت هذه الرسالة لأنك أو أحد آخر طلب كلمة لحسابك.\n" #~ "لكن ليس لدينا قيد مستخدم يستخدم عنوان البريد الإلكتروني %(email)s\n" #~ "في قاعدة بياناتنا.\n" #~ "\n" #~ "يمكنك تجاهل هذه الرسالة بأمان إذا لم تطلب إعادة ضبط كلمة المرور.\n" #~ "\n" #~ "إذا كنت أنت من طلب، يمكنك تسجيل حساب باستخدام الرابط في الأسفل." #~ msgid "The following email address is associated with your account:" #~ msgstr "عناوين البريد الإلكتروني التالية مربوطة مع حسابك:" #~ msgid "Change Email Address" #~ msgstr "تغيير البريد الإلكتروني" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "يرجى تسجيل الدخول مع واحد من حسابات الطرف الثالث الموجودة لديك‪.‬\n" #~ "كما يمكنك تسجيل حساب\n" #~ "في موقع %(site_name)s والدخول في الأسفل:" #~ msgid "or" #~ msgstr "أو" #~ msgid "change password" #~ msgstr "تغيير كلمة المرور" #~ msgid "OpenID Sign In" #~ msgstr "تسجيل الدخول عبر OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "عنوان البريد الإلكتروني هذا مقترن بالفعل بحساب آخر." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "لقد قمنا بإرسال رسالة اليك عبر البريد الإلكتروني. يرجى الاتصال بنا اذا " #~ "كنت لا تتلقى في غضون بضع دقائق." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "تسجيل الدخول و / أو كلمة المرور الذي حددته غير صحيحة." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "يمكن أن تحتوي أسماء المستخدمين إلا على الحروف، الأرقام و @/‪.‬/-/+/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "اسم المستخدم مسجل مسبقا. الرجاء اختيار اسم اخر‪.‬" #, fuzzy #~ msgid "Shopify Sign In" #~ msgstr "تسجيل الدخول Shopify" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "لقد اكّدت ان %(email)s هو من إحدى عناوين " #~ "للمستعمل %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "شكرا لاستخدام موقعنا!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "ارسلت رسالة التأكيد الى بريدك الالكتروني %(email)s" #~ msgid "Delete Password" #~ msgstr "احذف كلمة المرور" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "بامكانك حذف كلمة المرور بما انك قمت بتسجيل الدخول بواسطة OpenID" #~ msgid "delete my password" #~ msgstr "احذف كلمة المرور الخاصة بي" #~ msgid "Password Deleted" #~ msgstr "تم حذف كلمة المرور" django-allauth-65.0.2/allauth/locale/az/000077500000000000000000000000001467545753200200235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/az/LC_MESSAGES/000077500000000000000000000000001467545753200216105ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/az/LC_MESSAGES/django.po000066400000000000000000001473561467545753200234320ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Jeyhun Piriyev , 2023 # msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:02+0200\n" "Last-Translator: Jeyhun Piriyev \n" "Language-Team: Azerbaijani (Azerbaijan)\n" "Language: az\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Bu hesab hazırda aktiv deyil." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Siz əsas e-poçt ünvanınızı (%(email)s) silə bilməzsiniz." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Bu e-poçt ünvanı artıq bu hesabla əlaqələndirilib." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Göstərdiyiniz e-poçt ünvanı və/və ya şifrə düzgün deyil." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "İstifadəçi artıq bu e-poçt ünvanı ilə qeydiyyatdan keçib." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Zəhmət olmasa cari şifrənizi yazın." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Yanlış kod." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Yanlış şifrə." #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Yanlış Token" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Şifrə sıfırlama tokeni yanlışdır." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Siz %d-dən çox e-poçt ünvanı əlavə edə bilməzsiniz." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Həddindən artıq uğursuz giriş cəhdi. Biraz sonra yenidən cəhd edin." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "E-poçt ünvanı heç bir istifadəçi hesabına təyin edilməyib" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Əsas e-poçt ünvanınız təsdiqlənməlidir." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "İstifadəçi adı istifadə edilə bilməz. Zəhmət olmasa başqa istifadəçi adından " "istifadə edin." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Göstərdiyiniz istifadəçi adı və/yaxud şifrə düzgün deyil." #: account/adapter.py:741 msgid "Use your password" msgstr "Şifrənizi istifadə edin" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "Autentifikator tətbiqindən istifadə edin" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "gizli açar" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Əsas e-poçt ünvanınız təsdiqlənməlidir." #: account/apps.py:11 msgid "Accounts" msgstr "Hesablar" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Hər dəfə eyni şifrəni daxil etməlisiniz." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Şifrə" #: account/forms.py:93 msgid "Remember Me" msgstr "Məni xatırla" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-poçt ünvanı" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-poçt" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "İstifadəçi adı" #: account/forms.py:123 msgid "Username or email" msgstr "İstifadəçi adı və ya e-poçt" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Daxil ol" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Şifrəni unutmusan?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-poçt (təkrar)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "E-poçt ünvanı təsdiqi" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-poçt (istəyə bağlı)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Hər dəfə eyni e-poçtu daxil etməlisiniz." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Şifrə (təkrar)" #: account/forms.py:554 msgid "Current Password" msgstr "Mövcud şifrə" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Yeni şifrə" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Yeni şifrə (təkrar)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kod" #: account/models.py:26 msgid "user" msgstr "istifadəçi" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-poçt ünvanı" #: account/models.py:34 msgid "verified" msgstr "doğrulanmış" #: account/models.py:35 msgid "primary" msgstr "əsas" #: account/models.py:41 msgid "email addresses" msgstr "e-poçt ünvanları" #: account/models.py:150 msgid "created" msgstr "yaradılmış" #: account/models.py:151 msgid "sent" msgstr "göndərildi" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "açar" #: account/models.py:157 msgid "email confirmation" msgstr "e-poçt təsdiqi" #: account/models.py:158 msgid "email confirmations" msgstr "e-poçt təsdiqləri" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Siz iki faktorlu doğrulama ilə qorunan hesaba e-poçt ünvanı əlavə edə " "bilməzsiniz." #: mfa/adapter.py:35 #, fuzzy #| msgid "" #| "You cannot add an email address to an account protected by two-factor " #| "authentication." msgid "You cannot deactivate two-factor authentication." msgstr "" "Siz iki faktorlu doğrulama ilə qorunan hesaba e-poçt ünvanı əlavə edə " "bilməzsiniz." #: mfa/adapter.py:38 #, fuzzy #| msgid "" #| "You cannot add an email address to an account protected by two-factor " #| "authentication." msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Siz iki faktorlu doğrulama ilə qorunan hesaba e-poçt ünvanı əlavə edə " "bilməzsiniz." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Siz e-poçt ünvanınızı doğrulamayana qədər iki faktorlu doğrulamanı " "aktivləşdirə bilməzsiniz." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "gizli açar" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Bərpa kodları" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP Autentifikator" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Doğrulama kodu" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Şifrə" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Bu e-poçt ünvanı ilə artıq hesab mövcuddur. Lütfən, əvvəlcə həmin hesaba " "daxil olun, sonra %s hesabınızı birləşdirin." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Yanlış Token" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Hesabınızda şifrə quraşdırılmayıb." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Hesabınızın təsdiqlənmiş e-poçt ünvanı yoxdur." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third-party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Aşağıdakı üçüncü tərəf hesablarından hər hansı birini istifadə edərək " "hesabınıza daxil ola bilərsiniz:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Sosial hesab artıq başqa hesaba qoşulub." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sosial Hesablar" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "provayder" #: socialaccount/models.py:52 msgid "provider ID" msgstr "provayder ID" #: socialaccount/models.py:56 msgid "name" msgstr "ad" #: socialaccount/models.py:58 msgid "client id" msgstr "müştəri id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Tətbiq ID-si və ya istehlakçı açarı" #: socialaccount/models.py:63 msgid "secret key" msgstr "gizli açar" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API sirri, müştəri sirri və ya istehlakçı sirri" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Açar" #: socialaccount/models.py:81 msgid "social application" msgstr "sosial tətbiq" #: socialaccount/models.py:82 msgid "social applications" msgstr "sosial tətbiqlər" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "son giriş" #: socialaccount/models.py:120 msgid "date joined" msgstr "qoşulma tarixi" #: socialaccount/models.py:121 msgid "extra data" msgstr "əlavə məlumat" #: socialaccount/models.py:125 msgid "social account" msgstr "sosial hesab" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sosial hesablar" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) və ya giriş tokeni (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token sirri" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) və ya token yeniləyin (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "vaxtı bitir" #: socialaccount/models.py:174 msgid "social application token" msgstr "sosial tətbiq tokeni" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "sosial tətbiq tokenləri" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Yanlış profil məlumatı" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Daxil ol" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Ləğv et" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "\"%s\"-dən sorğu tokeni alınarkən yanlış cavab alındı. Cavab belə oldu: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "\"%s\"-dən giriş tokeni əldə edərkən yanlış cavab alındı." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "\"%s\" üçün heç bir sorğu tokeni saxlanılmadı." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "\"%s\" üçün heç bir giriş tokeni saxlanılmadı." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\" ünvanında şəxsi resurslara giriş yoxdur." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "\"%s\"-dən sorğu tokeni alınarkən uğursuz cavab alındı." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Hesab Aktiv Deyil" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Bu hesab aktiv deyil." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Girişi Təsdiqlə" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Hesabınızı qorumaq üçün lütfən, yenidən doğrulayın." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Alternativ variantlar" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "e-poçt təsdiqi" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Autentifikator kodunu daxil edin:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Təsdiq edin" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Daxil Ol" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-poçt Ünvanları" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Aşağıdakı e-poçt ünvanları hesabınızla əlaqələndirilir:" #: templates/account/email.html:25 msgid "Verified" msgstr "Doğrulanmış" #: templates/account/email.html:29 msgid "Unverified" msgstr "Doğrulanmamış" #: templates/account/email.html:34 msgid "Primary" msgstr "Əsas" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Əsas Et" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Doğrulamanı Yenidən Göndər" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Sil" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "E-poçt Ünvanı Əlavə Et" #: templates/account/email.html:70 msgid "Add Email" msgstr "E-poçt Əlavə Et" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Həqiqətən seçilmiş e-poçt ünvanını silmək istəyirsiniz?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Siz və ya başqası e-poçt ünvanından istifadə edərək\n" "hesab üçün qeydiyyatdan keçməyə çalışdığınız üçün bu e-məktubu alırsınız:\n" "\n" "%(email)s\n" "\n" "Lakin həmin e-poçt ünvanından istifadə edən hesab artıq mövcuddur. Bunu " "unutmusunuzsa, lütfən, hesabınızı bərpa etmək üçün unudulmuş şifrə " "prosedurundan istifadə edin:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Hesab Artıq Mövcuddur" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "%(site_name)s-dan Salam!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "%(site_name)s!\n" "%(site_domain)s istifadə etdiyiniz üçün təşəkkür edirik" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Cancel" msgid "Email Changed" msgstr "Ləğv et" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Siz %(email)s-u təsdiqlədiniz." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "e-poçt təsdiqi" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "%(user_display)s istifadəçisi %(site_domain)s-də hesabı qeydiyyatdan " "keçirmək üçün e-poçt ünvanınızı verdiyi üçün bu e-məktubu alırsınız.\n" "\n" "Bunun düzgün olduğunu təsdiqləmək üçün %(activate_url)s linkinə keçid edin." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Lütfən e-poçt ünvanınızı təsdiqləyin" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Sil" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Daxil Ol" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Şifrəniz dəyiştirildi." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Şifrə (təkrar)" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Siz və ya başqa biri hesabınız üçün şifrə sıfırlamasını tələb etdiyinə görə " "bu e-məktubu alırsınız.\n" "Əgər belə bir sorğu etməmisinizsə, bu e-məktubu gözardı edə bilərsiniz. " "Şifrənizi sıfırlamaq üçün aşağıdakı linkə keçid edin." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Əgər unutmusunuzsa, istifadəçi adınız %(username)s-dir." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Şifrə Sıfırlama E-poçtu" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Şifrəniz dəyiştirildi." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Şifrə Sıfırlama" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Şifrəniz dəyiştirildi." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Şifrə Sıfırlama" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "Hesablar" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "E-poçt Ünvanı" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Mövcud şifrə" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your email address is still pending verification:" msgid "Your email address is still pending verification." msgstr "E-poçt ünvanınız hələ də doğrulamanı gözləyir:" #: templates/account/email_change.html:41 #, fuzzy #| msgid "Cancel" msgid "Cancel Change" msgstr "Ləğv et" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Change Email" msgid "Change to" msgstr "E-poçt Dəyiş" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "E-poçt Dəyiş" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "E-poçt Ünvanını Təsdiqlə" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Lütfən, təsdiq edin ki, %(email)s " "%(user_display)s istifadəçisi üçün e-poçt ünvanıdır." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "%(email)s-u təsdiqləmək mümkün deyil, çünki, o, artıq başqa hesab tərəfindən " "təsdiqlənib." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Bu e-poçt təsdiqi linkinin vaxtı keçib və ya etibarsızdır. Lütfən, yeni e-poçt təsdiq sorğusu göndərin." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Hələ hesab yaratmamısınızsa, lütfən, əvvəlcə %(link)sqeydiyyatdan " "keçin%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Çıxış" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Hesabdan çıxmaq istədiyinizə əminsiniz?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Siz əsas e-poçt ünvanınızı (%(email)s) silə bilməzsiniz." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Təsdiq e-məktubu %(email)s ünvanına göndərildi." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Siz %(email)s-u təsdiqlədiniz." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s e-poçt ünvanı silindi." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s olaraq uğurla daxil oldun." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Siz hesabdan çıxdınız." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Şifrə uğurla dəyişdirildi." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Şifrə uğurla təyin edildi." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Əsas e-poçt ünvanı təyin edildi." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Şifrəni Dəyiş" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Şifrəni Unutmusunuz?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Şifrənizi unutmusunuz? Aşağıya e-poçt ünvanınızı daxil edin və biz sizə onu " "sıfırlamağa imkan verən e-məktub göndərəcəyik." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Şifrəmi Sıfırlayın" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Şifrənizi sıfırlamaqla bağlı hər hansı probleminiz olarsa, bizimlə əlaqə " "saxlayın." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Sizə e-məktub göndərdik. Əgər onu almamısınızsa, spam qovluğunuzu yoxlayın. " "Əks halda, bir neçə dəqiqə ərzində onu almasanız, bizimlə əlaqə saxlayın." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Yanlış Token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Şifrə sıfırlama linki etibarsız idi, ola bilsin ki, artıq istifadə olunub. " "Lütfən, yeni şifrə sıfırlamasını tələb " "edin." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Şifrəniz dəyiştirildi." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Şifrə Təyin Et" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Şifrənizi daxil edin:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 #, fuzzy #| msgid "Recovery Codes" msgid "Request Code" msgstr "Bərpa kodları" #: templates/account/request_login_code.html:30 #, fuzzy #| msgid "Alternative options" msgid "Other sign-in options" msgstr "Alternativ variantlar" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Qeydiyyatdan keçin" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Qeydiyyatdan Keç" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Artıq bir hesabınız var? Lütfən %(link)sdaxil olun%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Qeydiyyatdan Keç" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Alternative options" msgid "Other options" msgstr "Alternativ variantlar" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Qeydiyyat Bağlıdır" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Üzr istəyirik, lakin qeydiyyat hazırda bağlıdır." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Qeyd" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Siz artıq %(user_display)s kimi daxil olmusunuz." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Xəbərdarlıq:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Hazırda ayarlanmış e-poçt ünvanınız yoxdur. Siz mütləq e-poçt ünvanı əlavə " "etməlisiniz ki, bildirişlər ala, şifrənizi sıfırlayasınız və s." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "E-poçt Ünvanınızı Doğrulayın" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Doğrulama üçün sizə e-məktub göndərdik. Qeydiyyat prosesini yekunlaşdırmaq " "üçün verilən linki izləyin. Doğrulama e-məktubunu əsas gələnlər qutunuzda " "görmürsünüzsə, spam qovluğunuzu yoxlayın. Bir neçə dəqiqə ərzində doğrulama " "e-məktubunu almasanız, bizimlə əlaqə saxlayın." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Saytın bu hissəsi siz olduğunuzu təsdiq etməyimizi tələb edir\n" ".Bu məqsədlə sizdən e-poçt ünvanınızın sahibliyini\n" "doğrulamanızı tələb edirik." #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Doğrulama üçün\n" "sizə e-məktub göndərdik. Zəhmət olmasa həmin e-poçtun içindəki linkə keçid " "edin. Doğrulama e-poçtunu əsas gələnlər qutunuzda görmürsünüzsə, spam " "qovluğunuzu yoxlayın. Əks halda\n" "bir neçə dəqiqə ərzində onu almasanız, bizimlə əlaqə saxlayın." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Qeyd: siz hələ də e-poçt " "ünvanınızı dəyişə bilərsiniz." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Mesajlar:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menyu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Hesab Əlaqələri" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "İki Faktorlu Doğrulama" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Hesabınız iki faktorlu doğrulama ilə qorunur. Zəhmət olmasa autentifikator " "kodunu daxil edin:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Yeni bərpa kodları dəsti yaradıldı." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 #, fuzzy #| msgid "Recovery Codes" msgid "New Recovery Codes Generated" msgstr "Bərpa kodları" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Autentifikator tətbiqi aktivləşdirildi." #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "Authenticator app activated." msgid "Authenticator App Activated" msgstr "Autentifikator tətbiqi aktivləşdirildi." #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Autentifikator tətbiqi deaktiv edildi." #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "Authenticator app deactivated." msgid "Authenticator App Deactivated" msgstr "Autentifikator tətbiqi deaktiv edildi." #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "Yeni bərpa kodları dəsti yaradıldı." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Siz %(email)s-u təsdiqlədiniz." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Autentifikator Tətbiqi" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Autentifikator tətbiqindən istifadə edərək doğrulama aktivdir." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Autentifikator tətbiqi aktiv deyil." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Deaktiv et" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Aktivləşdir" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Bərpa kodları" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "Əlçatan %(total_count)s bərpa kodundan %(unused_count)s var." msgstr[1] "Əlçatan %(total_count)s bərpa kodundan %(unused_count)s var." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Bərpa kodları qurulmayıb." #: templates/mfa/index.html:96 msgid "View" msgstr "Bax" #: templates/mfa/index.html:102 msgid "Download" msgstr "Yüklə" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Yarat" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Yeni bərpa kodları dəsti yaradıldı." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Autentifikator kodunu daxil edin:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Hesabınız üçün yeni bərpa kodları dəsti yaratmaq üzrəsiniz." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Bu əməliyyat mövcud kodlarınızı etibarsız edəcək." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Siz əminsiniz?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "İstifadə edilməmiş kodlar" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Kodları yükləyin" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Yeni kodlar yarat" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Autentifikator Tətbiqini Aktivləşdirin" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Hesabınızı iki faktorlu doğrulama ilə qorumaq üçün autentifikator " "tətbiqinizlə aşağıdakı QR kodunu skan edin. Sonra, aşağıdakı proqram " "tərəfindən yaradılan doğrulama kodunu daxil edin." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Autentifikator sirri" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Siz bu sirri saxlaya və ondan autentifikator tətbiqinizi daha sonra yenidən " "quraşdırmaq üçün istifadə edə bilərsiniz." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Autentifikator Tətbiqini Deaktiv Et" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Siz autentifikator tətbiqinə əsaslanan doğrulamanı deaktiv etmək üzrəsiniz. " "Siz əminsiniz?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "gizli açar" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "gizli açar" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Hesabdan çıxmaq istədiyinizə əminsiniz?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "gizli açar" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Doğrulanmamış" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "gizli açar" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Mövcud şifrə" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "yaradılmış" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Sosial Şəbəkəyə Giriş Xətası" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Sosial şəbəkə hesabınız vasitəsilə daxil olmağa cəhd edərkən xəta baş verdi." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Aşağıdakı üçüncü tərəf hesablarından hər hansı birini istifadə edərək " "hesabınıza daxil ola bilərsiniz:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Hazırda bu hesaba qoşulmuş heç bir sosial şəbəkə hesabınız yoxdur." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Üçüncü Tərəf Hesabı Əlavə Et" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a Third-Party Account" msgid "Third-Party Account Connected" msgstr "Üçüncü Tərəf Hesabı Əlavə Et" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a Third-Party Account" msgid "Third-Party Account Disconnected" msgstr "Üçüncü Tərəf Hesabı Əlavə Et" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "%(provider)s ilə əlaqə" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Siz %(provider)s-dən yeni üçüncü tərəf hesabını qoşmaq üzrəsiniz." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "%(provider)s vasitəsi ilə daxil olun" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Siz %(provider)s-dən üçüncü tərəf hesabından istifadə etməklə daxil olmaq " "üzrəsiniz." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Davam et" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Giriş Ləğv Edildi" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Mövcud hesablarınızdan birini istifadə edərək saytımıza daxil olmağı ləğv " "etmək qərarına gəldiniz. Bu səhvdirsə, daxil olun." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Sosial hesab bağlandı." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Sosial hesabın əlaqəsi kəsilib." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Siz \n" " %(site_name)s hesabına daxil olmaq üçün %(provider_name)s hesabınızdan " "istifadə etmək üzrəsiniz. Son addım olaraq, aşağıdakı formu doldurun:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Və ya üçüncü tərəf istifadə edin" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Address" msgid "IP Address" msgstr "E-poçt Ünvanı" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Mövcud şifrə" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Hesab Əlaqələri" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Şifrə ən az {0} simvoldan ibarət olmalıdır." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Sizin və ya başqa birinin istifadəçi hesabınız üçün\n" #~ "şifrə tələb etdiyini bildirmək üçün bu e-məktubu alırsınız. Lakin, bizim " #~ "verilənlər bazamızda\n" #~ "%(email)s e-poçt ünvanına sahib heç bir istifadəçi məlumatı yoxdur.\n" #~ "\n" #~ "Şifrənin sıfırlanmasını tələb etməmisinizsə, bu e-məktubu gözardı edə " #~ "bilərsiniz.\n" #~ "\n" #~ "Əgər bu siz idinizsə, siz aşağıdakı linkdən istifadə edərək hesaba daxil " #~ "ola bilərsiniz." #~ msgid "The following email address is associated with your account:" #~ msgstr "Aşağıdakı e-poçt ünvanı hesabınızla əlaqələndirilib:" #~ msgid "Change Email Address" #~ msgstr "E-poçt Ünvanını Dəyiş" django-allauth-65.0.2/allauth/locale/bg/000077500000000000000000000000001467545753200200015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/bg/LC_MESSAGES/000077500000000000000000000000001467545753200215665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/bg/LC_MESSAGES/django.po000066400000000000000000001576011467545753200234020ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:14+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Този акаунт в момента е неактивен." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Не можете да премахнете основния си e-mail адрес (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Този e-mail адрес вече е свързан с този акаунт." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "E-mail адресът и/или паролата, които въведохте, са грешни." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Вече има регистриран потребител с този e-mail адрес." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Моля, въведете вашата текуща парола." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Текуща парола" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Грешен код" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Невалиден код за възстановяване на парола." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Не можете да добавяте повече от %d e-mail адреса." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Твърде много неуспешни опити за влизане. Опитайте отново по-късно." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Няма потребител с този e-mail адрес." #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Основният ви e-mail адрес трябва да бъде потвърден." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Това потребителско име не може да бъде използвано. Моля, изберете друго." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Потребителското име и/или паролата, които въведохте, са грешни." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Забравена парола?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "таен код" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "таен ключ" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Основният ви e-mail адрес трябва да бъде потвърден." #: account/apps.py:11 msgid "Accounts" msgstr "Акаунти" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Трябва да въведете една и съща парола." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Парола" #: account/forms.py:93 msgid "Remember Me" msgstr "Запомни ме" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-mail адрес" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Потребителско име" #: account/forms.py:123 msgid "Username or email" msgstr "Потребителско име или e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Акаунт" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Забравена парола?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (отново)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Потвърждение на e-mail адрес" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (опционален)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Трябва да въведете един и същ email." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Парола (отново)" #: account/forms.py:554 msgid "Current Password" msgstr "Текуща парола" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Нова парола" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Нова парола (отново)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "потребител" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-mail адрес" #: account/models.py:34 msgid "verified" msgstr "потвърден" #: account/models.py:35 msgid "primary" msgstr "основен" #: account/models.py:41 msgid "email addresses" msgstr "email адреси" #: account/models.py:150 msgid "created" msgstr "създадено" #: account/models.py:151 msgid "sent" msgstr "изпратено" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "ключ" #: account/models.py:157 msgid "email confirmation" msgstr "email потвърждение" #: account/models.py:158 msgid "email confirmations" msgstr "email потвърждения" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "таен ключ" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Парола" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Вече съществува акаунт с този e-mail адрес. Моля, първо влезте в този акаунт " "и тогава свържете вашия %s акаунт." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Грешен код" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Вашият акаунт няма парола." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Вашият акаунт няма потвърден e-mail адрес." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "Можете да влизате в акаунта си чрез следните външни акаунти:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Социалният акаунт вече е свързан с друг акаунт." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Социални акаунти" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "доставчик" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "доставчик" #: socialaccount/models.py:56 msgid "name" msgstr "име" #: socialaccount/models.py:58 msgid "client id" msgstr "id на клиент" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID на приложение, или ключ на консуматор" #: socialaccount/models.py:63 msgid "secret key" msgstr "таен ключ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "таен ключ на API, клиент или консуматор" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Ключ" #: socialaccount/models.py:81 msgid "social application" msgstr "социално приложение" #: socialaccount/models.py:82 msgid "social applications" msgstr "социални приложения" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "последно влизане" #: socialaccount/models.py:120 msgid "date joined" msgstr "дата на регистрация" #: socialaccount/models.py:121 msgid "extra data" msgstr "допълнителни данни" #: socialaccount/models.py:125 msgid "social account" msgstr "социален акаунт" #: socialaccount/models.py:126 msgid "social accounts" msgstr "социални акаунти" #: socialaccount/models.py:160 msgid "token" msgstr "код" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) или access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "таен код" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) или refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "изтича" #: socialaccount/models.py:174 msgid "social application token" msgstr "код на социално приложение" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "кодове на социални приложения" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Невалидни профилни данни" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Акаунт" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Грешен отговор при получаване на код за заявка от \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Грешен отговор при получаване на код за достъп от \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Няма запазен код за заявка за \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Няма запазен код за достъп за \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Няма достъп до лични данни при \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Грешен отговор при получаване на код за заявка от \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Неактивен акаунт" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Този акаунт е неактивен." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Потвърждение на e-mail адрес" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "email потвърждение" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "таен код" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Потвърди" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Вход" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-mail адреси" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Следните e-mail адреси са свързани с вашия акаунт:" #: templates/account/email.html:25 msgid "Verified" msgstr "Потвърден" #: templates/account/email.html:29 msgid "Unverified" msgstr "Непотвърден" #: templates/account/email.html:34 msgid "Primary" msgstr "Основен" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Направи основен" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Изпрати потвърждение отново" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Премахни" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Добяне на е-mail адрес" #: templates/account/email.html:70 msgid "Add Email" msgstr "Добави e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Наистина ли искате да премахнете избрания e-mail адрес?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Здравейте от %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Благодарим, че ползвате %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "E-mail адрес" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Потвърдихте e-mail адрес %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "email потвърждение" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Получавате този e-mail, защото потребител %(user_display)s е дал вашия e-" "mail адрес за да регистрира акаунт в %(site_domain)s.\n" "\n" "За да потвърдите, че това е вярно, посетете %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Моля, потвърдете вашия e-mail адрес" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Премахни" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Вход" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Паролата ви е сменена." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Парола (отново)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Получавате този e-mail, защото вие или някой друг е поискал парола за вашия " "потребителски акаунт.\n" "Можете да го пренебрегнете, ако не сте поискали възстановяване на парола. " "Кликнете линка по-долу за да възстановите вашата парола." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "В случай, че сте забравили, вашето потребителско име е %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Възстановяване на парола" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Паролата ви е сменена." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Възстановяване на парола" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Паролата ви е сменена." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Възстановяване на парола" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "Акаунти" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "E-mail адреси" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Текуща парола" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Основният ви e-mail адрес трябва да бъде потвърден." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Потвърждение на e-mail адрес" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Моля, потвърдете, че %(email)s е e-mail " "адрес на потребител %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Социалният акаунт вече е свързан с друг акаунт." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Този линк за потвърждение на e-mail е изтекъл или невалиден. Моля, подайте нова заявка за потвърждение на e-mail." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ако все още не сте създали акаунт, моля, %(link)sрегистрирайте " "се%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Изход" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Сигурни ли сте, че искате да излезете?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Не можете да премахнете основния си e-mail адрес (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Потвърждение на e-mail адрес изпратено на %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Потвърдихте e-mail адрес %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Премахнат e-mail адрес %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Успешно влязохте като %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Излязохте." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Паролата беше сменена успешно." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Паролата беше запазена успешно." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Основният e-mail адрес беше избран." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Смяна на парола" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Забравена парола?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Забравили сте вашата парола? Въведете вашия e-mail адрес по-долу и ще ви " "пратим e-mail как да я възстановите." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Възстанови паролата ми" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Моля, свържете се с нас, ако имате проблеми с възстановяването на вашата " "парола." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent you an e-mail. If you have not received it please check your " #| "spam folder. Otherwise contact us if you do not receive it in a few " #| "minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Изпратихме ви електронно писмо. То може да пристигнало в папката Спам. Моля, " "свържете се с нас, ако не го получите до няколко минути." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Грешен код" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Линкът за възстановяване на парола е невалиден, може би защото вече е бил " "използван. Моля, заявете ново " "възстановяване на парола." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Паролата ви е сменена." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Създаване на парола" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Забравена парола?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Регистрация" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Регистрация" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Вече имате акаунт? Тогава, моля, %(link)sвлезте%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Регистрация" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Регистрацията е затворена" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Съжаляваме, но в момента регистрацията е затворена." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Забележка" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "вече сте влезли като %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Предупреждение:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "В момента нямате регистриран e-mail адрес. Препоръчително е да добавите e-" "mail адрес за да можете да получавате известия, да възстановявате паролата " "си, и т.н." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Потвърдете вашия e-mail адрес" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. If you do not see the verification e-mail " #| "in your main inbox, check your spam folder. Please contact us if you do " #| "not receive the verification e-mail within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Изпратихме ви e-mail за потвърждение. Последвайте посочения в него линк за " "да завършите процеса на регистрация. То може да е пристигнало в папката " "Спам. Моля, свържете се с нас, ако не го получите до няколко минути." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Тази част на сайта изисква да проверим, че сте който/която твърдите.\n" "За тази цел изискваме да\n" "потвърдите притежанието на вашия e-mail адрес. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside that e-mail. If you do not " #| "see the verification e-mail in your main inbox, check your spam folder. " #| "Otherwise\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Изпратихме ви e-mail за потвърждение. То може да е попаднало в папката Спам. " "Моля, кликнете линка в него. Свържете се с нас, ако не го получите до " "няколко минути." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Забележка: можете да смените " "вашия e-mail адрес." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Свързани акаунти" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "таен код" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "таен код" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Потвърдихте e-mail адрес %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "таен код" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "таен код" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "таен ключ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "таен ключ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Сигурни ли сте, че искате да излезете?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "таен ключ" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Непотвърден" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "таен ключ" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Текуща парола" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "създадено" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Грешка при вход чрез социална мрежа" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Възникна грешка при опита за влизане чрез вашия акаунт от социална мрежа." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Можете да влизате в акаунта си чрез следните външни акаунти:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "В момента нямате акаунти от социални мрежи, свързани с този акаунт." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Добавяне на външен акаунт" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Добавяне на външен акаунт" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Добавяне на външен акаунт" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Вход прекъснат" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Прекъснахте влизането в нашия сайт чрез ваш съществуващ акаунт. Ако това е " "било грешка, моля, влезте." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Социалният акаунт беше свързан." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Социалният акаунт беше изключен." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "На път сте да използвате вашия %(provider_name)s акаунт за вход в\n" "%(site_name)s. Като последна стъпка, моля, попълнете следната форма:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "E-mail адреси" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Текуща парола" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Свързани акаунти" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Паролата трябва да бъде поне {0} символа." #, fuzzy, python-format #~| msgid "" #~| "You are receiving this e-mail because you or someone else has requested " #~| "a\n" #~| "password for your user account. However, we do not have any record of a " #~| "user\n" #~| "with email %(email)s in our database.\n" #~| "\n" #~| "This mail can be safely ignored if you did not request a password " #~| "reset.\n" #~| "\n" #~| "If it was you, you can sign up for an account using the link below." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Получавате този e-mail, защото вие или някой друг е поискал парола за " #~ "вашия потребителски акаунт.\n" #~ "На сървъра обаче не беше намерен потребител свързван с електронния адрес " #~ "%(email)s.\n" #~ "\n" #~ "Можете да пренебрегнете това писмо, ако не сте поискали възстановяване на " #~ "парола. Кликнете линка по-долу, за да направите нов акаунт." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Следните e-mail адреси са свързани с вашия акаунт:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Потвърждение на e-mail адрес" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Моля, влезте с някой\n" #~ "от съществуващите ви външни акаунти. Или %(link)sсе регистрирайте\n" #~ "за %(site_name)s акаунт и влезте по-долу:" #~ msgid "or" #~ msgstr "или" #~ msgid "change password" #~ msgstr "смени паролата" #~ msgid "OpenID Sign In" #~ msgstr "Вход с OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Този e-mail адрес вече е свързан с друг акаунт." django-allauth-65.0.2/allauth/locale/ca/000077500000000000000000000000001467545753200177745ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ca/LC_MESSAGES/000077500000000000000000000000001467545753200215615ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ca/LC_MESSAGES/django.po000066400000000000000000001507451467545753200233770ustar00rootroot00000000000000# DJANGO-ALLAUTH. # Copyright (C) 2016 # This file is distributed under the same license as the django-allauth package. # # Translators: # Marc Seguí Coll , 2022. # msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-26 16:15+0000\n" "Last-Translator: Ajordat \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Ara mateix aquest compte està inactiu." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "No podeu eliminar el vostre correu electrònic principal." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Aquest correu electrònic ja està associat amb aquest compte." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "" "El correu electrònic i/o la contrasenya que heu especificat no són correctes." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "" "Un usuari ja ha estat registrat amb aquesta direcció de correu electrònic." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Si us plau, escriviu la vostra contrasenya actual." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Codi incorrecte." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Contrasenya actual." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Clau no vàlida o caducada." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "El token per reiniciar la contrasenya no és vàlid." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "No es poden afegit més de %d adreces de correu electrònic." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Massa intents fallits. Intenteu-ho de nou més tard." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "El correu electrònic no està assignat a cap compte d'usuari" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "La vostra adreça de correu electrònic principal ha de ser verificada." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Aquest nom d'usuari no pot ser emprat. Si us plau utilitzeu-ne un altre." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "L'usuari i/o la contrasenya que heu especificat no són correctes." #: account/adapter.py:741 msgid "Use your password" msgstr "Utilitzeu la vostra paraula de pas" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Utilitzar una aplicació d’autenticació o un codi" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Utilitzar una clau de seguretat" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Marqueu l’adreça de correu seleccionada com a verificada" #: account/apps.py:11 msgid "Accounts" msgstr "Comptes" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Heu d'escriure la mateixa contrasenya cada cop." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Contrasenya" #: account/forms.py:93 msgid "Remember Me" msgstr "Recordar-me" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Correu electrònic" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Correu electrònic" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nom d'usuari" #: account/forms.py:123 msgid "Username or email" msgstr "Nom d'usuari o correu electrònic" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Iniciar sessió" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Heu oblidat la contrasenya?" #: account/forms.py:299 msgid "Email (again)" msgstr "Correu electrònic (un altre cop)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Confirmació de direcció de correu electrònic" #: account/forms.py:311 msgid "Email (optional)" msgstr "Correu electrònic (opcional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Heu d'escriure el mateix correu electrònic cada cop." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Contrasenya (de nou)" #: account/forms.py:554 msgid "Current Password" msgstr "Contrasenya actual" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nova contrasenya" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nova contrasenya (de nou)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Codi" #: account/models.py:26 msgid "user" msgstr "usuari" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "correu electrònic" #: account/models.py:34 msgid "verified" msgstr "verificat" #: account/models.py:35 msgid "primary" msgstr "principal" #: account/models.py:41 msgid "email addresses" msgstr "correus electrònics" #: account/models.py:150 msgid "created" msgstr "creat" #: account/models.py:151 msgid "sent" msgstr "enviat" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "clau" #: account/models.py:157 msgid "email confirmation" msgstr "confirmació de correu electrònic" #: account/models.py:158 msgid "email confirmations" msgstr "confirmacions de correu electrònic" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "No podeu afegir una adreça de correu electrònic a un compte protegit per " "l'autenticació de dos factors." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "No podeu desactivar el doble factor d’autenticació." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "No podeu generar codis de recuperació sense tindre activat el doble factor " "d’autenticació." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "No podeu activar l'autenticació de dos factors fins que no hàgiu verificat " "la vostra adreça de correu electrònic." #: mfa/adapter.py:141 msgid "Master key" msgstr "Clau mestra" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Clau de recanvi" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Clau n. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Codis de recuperació" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Autenticador TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Codi de l’autenticador" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Sense contrasenya" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Habilitar operacions sense contrasenya permet iniciar la sessió utilitzant " "aquesta clau, però imposa requisits adicionals com la biometrica o protecció " "per PIN." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Ja existeix un compte associat a aquesta adreça de correu electrònic. Si us " "plau, primer identifiqueu-vos utilitzant aquest compte, i després vinculeu " "el vostre compte %s." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Token invàlid." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "El vostre compte no té una contrasenya definida." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "El vostre compte no té un correu electrònic verificat." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "No podeu desconnectar l'últim dels vostres comptes de tercers." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "El compte de xarxa social ja està connectada a un compte diferent." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Comptes de xarxes socials" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "proveïdor" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID de proveïdor" #: socialaccount/models.py:56 msgid "name" msgstr "nom" #: socialaccount/models.py:58 msgid "client id" msgstr "identificador client" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Identificador de App o clau de consumidor" #: socialaccount/models.py:63 msgid "secret key" msgstr "clau secreta" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" "frase secrete de API, frase secreta client o frase secreta de consumidor" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Clau" #: socialaccount/models.py:81 msgid "social application" msgstr "aplicació de xarxa social" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplicacions de xarxes socials" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "darrer inici de sessió" #: socialaccount/models.py:120 msgid "date joined" msgstr "data d'incorporació" #: socialaccount/models.py:121 msgid "extra data" msgstr "dades extra" #: socialaccount/models.py:125 msgid "social account" msgstr "compte de xarxa social" #: socialaccount/models.py:126 msgid "social accounts" msgstr "comptes de xarxes socials" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) o token d'accés (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "frase secreta de token" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) o token de refrescament (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "expira el" #: socialaccount/models.py:174 msgid "social application token" msgstr "token d'aplicació de xarxa social" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokens d'aplicació de xarxa social" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Dades de perfil invàlides" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Iniciar sessió" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Cancel·lar" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Resposta invàlida a l'hora d'obtenir token des de “%s”. La resposta fou: " "\"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Resposta invàlida a l'hora d'obtenir token d'accés de \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "No hi ha token de sol·licitud guardat per \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "No hi ha token d'accés guardat per \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Sense accés recursos privats de \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Resposta invàlida a l'hora d'obtenir token de sol·licitud de \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Compte inactiu" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Aquest compte està inactiu." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Confirmeu l’accés" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" "Sisplau, torneu-vos a autenticar per tal de mantenir el vostre compte segur." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Opcions alternatives" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "Verificació de correu electrònic" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Entreu un codi d’autenticació de correu" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Hem enviat un codi a %(email_link)s. El codi caduca en breu, així que si us " "plau introduïu-lo aviat." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Confirmar" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Iniciar sessió" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Introduïu el codi d'inici de sessió" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Adreces de correu electrònic" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "" "Les següents adreces de correu electrònic estan associades al vostre compte:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verificat" #: templates/account/email.html:29 msgid "Unverified" msgstr "Sense verificar" #: templates/account/email.html:34 msgid "Primary" msgstr "Principal" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Definir com a principal" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Reenviar Verificació" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Eliminar" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Afegir adreça de correu electrònic" #: templates/account/email.html:70 msgid "Add Email" msgstr "Afegir correu electrònic" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "" "Esteu segurs de voler eliminar l'adreça de correu electrònic seleccionada?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Heu rebut aquest correu electrònic perquè vostè o algú altre s'ha intentat " "registrar\n" "per obtenir un compte amb aquest correu:\n" "\n" "%(email)s\n" "\n" "No obstant això, ja existeix un compte amb aquesta adreça electrònica. En " "cas que\n" "ho hàgiu oblidat, utilitzeu el servei de recuperació de contrasenya oblidada " "per\n" "recuperar el vostre compte:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "El compte ja existeix" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Hola des de %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Gràcies per utilitzar %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Heu rebut aquest correu perquè el següent canvi ha estat fet al vostre " "compte:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Si no reconeixeu aquest canvi, premeu precaucions de manera immediata. El " "canvi ha estat originat des de:\n" "\n" "- Adreça IP: %(ip)s\n" "- Navegador: %(user_agent)s\n" "- Data: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" "El vostre correu ha canviat. Correu anterior: %(from_email)s nou correu: " "%(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Correu electròni canviat" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "El vostre correu ha estat confirmat." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Confirmació de correu electrònic" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Heu rebut aquest missatge perquè l'usuari %(user_display)s ha proporcionat " "la vostra adreça per registrar un compte a %(site_domain)s." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "El seu codi de verificació per correu electrònic es troba a continuació. Si " "us plau, introdueixi'l a la finestra oberta del navegador." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Per confirmar que això és correcte, aneu a %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Si us plau, confirmeu la vostra adreça de correu electrònic" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "El correu %(deleted_email)s s'ha eliminat del vostre compte." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Correu esborrat" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "El seu codi d'inici de sessió es troba a continuació. Si us plau, " "introdueixi'l a la finestra oberta del navegador." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Aquest correu es pot ignorar de manera segura si vostè no ha iniciat aquesta " "acció." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Codi d'inici de sessió" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "La vostra contrasenya ha canviat." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "La vostra contrasenya ha canviat" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Heu rebut aquest correu electrònic perquè vosaltres o una altra persona heu " "sol·licitat una contrasenya per al vostre compte d'usuari.\n" "Es pot ignorar de forma segura si no es va sol·licitar el restabliment de " "contrasenya. Seguiu el següent enllaç per restablir la vostra contrasenya." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "En cas d'haver-lo oblidat, el vostre nom d'usuari és %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Correu electrònic per restablir contrasenya" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "S’ha restablert la vostra contrasenya." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Restablir Contrasenya" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "La vostra contrasenya ha canviat." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Contrasenya establerta" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Està rebent aquest correu perquè vostè, o algú altre, ha intentat accedir a " "un compte amb el correu %(email)s. No obstant això, no tenim constància de " "cap compte associat a aquest correu electrònic a la nostra base de dades." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Si era vostè, pot registrar-se per un compte amb l'enllaç a continuació." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Compte desconegut" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Adreces de correu electrònic" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Correu actual" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Canviant a" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "" "La vostra adreça de correu electrònic encara està pendent de ser verificada." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Cancel·lar el canvi" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Canviar a" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Canviar correu electrònic" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Confirmar adreça de correu electrònic" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Si us plau confirmeu que %(email)s és una " "adreça de correu electrònic de l'usuari %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "No es pot confirmar %(email)s perquè ja està confirmat en un compte diferent." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Aquest enllaç de verificació de correu electrònic ha expirat o és invàlid. " "Si us plau, sol·liciteu una nova verificació per " "correu electrònic.." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Si encara no heu creat un compte, llavors si us plau %(link)sregistreu-" "vos%(end_link)s primer." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Inicia sessió amb un clau d'accés" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Enviï'm un codi d'inici de sessió" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Tancar sessió" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Esteu segurs de voler tancar sessió?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "No podeu eliminar el vostre correu electrònic principal (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Correu electrònic de confirmació enviat a %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Heu confirmat %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Eliminat correu electrònic %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Heu iniciat sessió exitosament com a %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Heu tancat sessió." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "S'ha enviat un codi d'inici de sessió a %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Contrasenya canviada amb èxit." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Contrasenya establerta amb èxit." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Adreça de correu electrònic principal establerta." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Canviar Contrasenya" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Heu oblidat la vostra contrasenya?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Heu oblidat la vostra contrasenya? Introduïu el vostre correu electrònic i " "us enviarem un correu que us permetrà restablir-la." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Restablir la meva contrasenya" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Si us plau contacteu-nis si teniu algun problema per restablir la vostra " "contrasenya." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Us hem enviat un correu electrònic. Si us plau contacteu-nos si no el rebeu " "en uns minuts." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Hi ha un problema amb el token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "L'enllaç per restablir la contrasenya és invàlid, probablement porquè ja ha " "estat utilitzat. Si us plau soliciteu restablir la contrasenya novament." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "La vostra contrasenya ha canviat." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Establir contrasenya" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Introduïu la vostra paraula de pas:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Rebrà un correu electrònic amb un codi especial per iniciar sessió sense " "contrasenya." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Sol·licitar codi" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Opcions alternatives d'inici de sessió" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registrar-se" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registrar-se" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Ja teniu un compte? Si us plau %(link)sinicieu sessió%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Registra't amb un clau d'accés" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Registrar clau d'accés" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Opcions alternatives" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registre tancat" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Ho sentim, en aquest moment el registre está tancat." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Nota" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "ja heu iniciat sessió com a %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Advertència:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Actualment no teniu cap adreça de correu electrònic definida. Hauríeu " "d'afegir una adreça de correu electrònic per poder rebre notificacions, " "restablir la contrasenya, etc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifiqueu la vostra direcció de correu electrònic" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Us hem enviat un correu electrònic per la seva verificació. Seguiu l'enllaç " "per completar el procés de registre. Si us plau contacteu-nos si no el rebeu " "en uns minuts." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Aquesta part del lloc web requereix que verifiquem que\n" "sou qui dieu ser. Per això us requerim que verifiqueu la\n" "propietat del vostre correu electrònic. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Us hem enviat un correu electrònic per la vostra\n" "verificació. Si us plau accediu al link dins el correu electrònic. Si no " "veieu el correu de verificació a la vostra bústia principal, comproveu la " "carpeta d'spam. D'altra banda\n" "contacteu-nos si no el rebeu en uns minuts." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Nota: encara podeu canviar la " "vostra adreça de correu electrònic." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Missatges:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menú:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Connexions de Compte" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Autenticació de doble factor (TFA)" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sessions" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "El teu compte està protegit per doble factor d’autenticació. Sisplau, entreu " "el codi de l’autenticador:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "S’ha generat un nou conjunt de codis de recuperació de doble factor " "d’autenticació." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "S’ha generat un nou codi de recuperació" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "App d’autenticació activada." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "App d’autenticació activada" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "App d’autenticació desactivada." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "App d’autenticació desactivada" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Una nova clau de seguretat ha estat afegida." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Clau de Seguretat Afegida" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your email has been confirmed." msgid "A security key has been removed." msgstr "El vostre correu ha estat confirmat." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "App d’autenticació" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "L’autenticació està fent servir una app d’autenticació activa." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "L’app d’autenticació no està activa." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Desactivat" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Activat" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Codis de recuperació" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Hi ha un %(unused_count)s d’un total de %(total_count)s codi de recuperació " "disponible." msgstr[1] "" "Hi ha %(unused_count)s d’un total de %(total_count)s codis de recuperació " "disponibles." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "No heu definit codis de recuperació." #: templates/mfa/index.html:96 msgid "View" msgstr "Vista" #: templates/mfa/index.html:102 msgid "Download" msgstr "Descarrega" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Generar" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Un nou conjunt de codis de recuperació ha estat generat." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Entreu un codi d’autenticació:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Esteu a punt de generar un nou conjunt de codis de recuperació pel vostre " "compte." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Aquesta acció invalidarà els vostres codis existents." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Esteu segur?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Codis no utilitzats" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Descarrega els codis" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Genera nous codis" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Activa la App d’autenticació" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Per protegir el vostre compte amb doble factor d’autenticació, escanejeu el " "codi QR de sota amb la vostra App d’autenticació. Llavors, introduïu el codi " "de verificació generat per l’App a sota." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Secret d’autenticador" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Podeu emmagatzemar aquest secret i usar-lo per reinstal·lar la vostra app " "d’autenticació més endavant." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Desactiva l’App d’autenticació" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Esteu a punt de desactivar la seguretat basada en app d’autenticació. " "N’esteu segurs?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "clau secreta" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "clau secreta" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Esteu segurs de voler tancar sessió?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "clau secreta" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Sense verificar" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "clau secreta" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Contrasenya actual" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "creat" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Ha fallat l’autenticació de tercers" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "S'ha produït un error intentant iniciar sessió a través del vostre compte de " "xarxa social." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Podeu iniciar sessió amb algun dels següents comptes de tercers:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Actualment no tens cap compte de tercers associat a aquest compte." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Afegir un compte de tercers" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "El compte de tercers des de %(provider)s ha estat vinculat al teu compte." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Compte de tercers vinculat" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "El compte de tercers des de %(provider)s ha estat desvinculat al teu compte." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Compte de tercers desvinculat" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Connectar %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Esteu a punt de connectar un nou compte extern des de %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Iniciar sessió via %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Esteu a punt d'iniciar sessió utilitzant un compte extern des de " "%(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Continuar" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Inici de sessió cancel·lat" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Heu decidit cancel·lar l'inici de sessió al vostre lloc web utilitzant un " "dels vostres comptes existents. Si ha estat un error, si us plau inicieu sessió." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "El compte de xarxa social ha estat connectat." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "El compte de xarxa social s'ha desconnectat." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Esteu a punt d'utilitzar el vostre compte de %(provider_name)s per iniciar " "sessió a\n" "%(site_name)s. Com a pas final, si us plau completeu el següent formulari:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "O utilitzeu un compte de tercers" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Sortiu de totes les altres sessions." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Ha començat a les" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "Adreça IP" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Navegador" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Vist darreranent" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Actual" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Tanca les altres sessions" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Sessions de l’usuari" #: usersessions/models.py:92 msgid "session key" msgstr "clau de sessió" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Connexions de Compte" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "La contrasenya ha de contenir al menys {0} caràcters." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Has rebut aquest correu electrònic perquè vosaltres o algú altre heu " #~ "sol·licitat una\n" #~ "contrasenya per al vostre compte d'usuari. Tot i això, no tenim cap " #~ "registre d'un usuari\n" #~ "amb correu electrònic %(email)s a la nostra base de dades.\n" #~ "\n" #~ "Aquest correu es pot ignorar de forma segura si no heu sol·licitat un " #~ "canvi de contrasenya.\n" #~ "\n" #~ "Si heu estat vosaltres, podeu registrar un compte d'usuari utilitzant el " #~ "link de sota." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "" #~ "Les següents adreces de correu electrònic estan associades al vostre " #~ "compte:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Confirmar adreça de correu electrònic" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Si us plau, inicieu sessió amb un\n" #~ "compte d'una altra xarxa social. O %(link)sregistreu-vos \n" #~ "com a usuari de %(site_name)s i inicieu sessió a continuació:" #~ msgid "or" #~ msgstr "o" #~ msgid "change password" #~ msgstr "canviar la contrasenya" #~ msgid "OpenID Sign In" #~ msgstr "Iniciar sessió amb OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Aquest correu electrònic ja està associat amb un altre compte." django-allauth-65.0.2/allauth/locale/cs/000077500000000000000000000000001467545753200200165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/cs/LC_MESSAGES/000077500000000000000000000000001467545753200216035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/cs/LC_MESSAGES/django.po000066400000000000000000001534211467545753200234130ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Tomas Marcik , 2013. # Beda Kosata , 2018. # Filip Dobrovolny , 2023. # msgid "" msgstr "" "Project-Id-Version: 0.55\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-25 06:15+0000\n" "Last-Translator: Jakub Boukal \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n " "<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Účet je v tuto chvíli neaktivní." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Nemůžete odstranit primární e-mailovou adresu." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Tento e-mail je již k tomuto účtu přiřazen." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Zadaný e-mail nebo heslo není správné." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Uživatel s tímto e-mailem je již registrován." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Prosím, zadejte svoje současné heslo." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Nesprávný kód." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Nesprávné heslo." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Neplatný klíč." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Token pro reset hesla není platný." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Nelze přidat více než %d e-mailových adres." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Příliš mnoho pokusů o přihlášení. Zkuste to prosím později." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "E-mail není přiřazen k žádnému účtu" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Vaše primární e-mailová adresa musí být ověřena." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Toto uživatelské jméno nemůže být zvoleno. Prosím, zvolte si jiné." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Zadané uživatelské jméno nebo heslo není správné." #: account/adapter.py:741 msgid "Use your password" msgstr "Zadejte své heslo" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Použijte ověřovací aplikaci nebo kód" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Zadejte tajný klíč" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Označ vybrané e-mailové adresy jako ověřené" #: account/apps.py:11 msgid "Accounts" msgstr "Účty" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Hesla se musí shodovat." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Heslo" #: account/forms.py:93 msgid "Remember Me" msgstr "Zapamatovat" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-mailová adresa" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Uživatelské jméno" #: account/forms.py:123 msgid "Username or email" msgstr "Uživatelské jméno nebo e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Přihlášení" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Zapoměli jste heslo?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (znovu)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Potrvzení e-mailové adresy" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (nepovinné)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Vložené e-maily se musí shodovat." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Heslo (znovu)" #: account/forms.py:554 msgid "Current Password" msgstr "Současné heslo" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nové heslo" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nové heslo (znovu)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kód" #: account/models.py:26 msgid "user" msgstr "uživatel" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-mailová adresa" #: account/models.py:34 msgid "verified" msgstr "ověřeno" #: account/models.py:35 msgid "primary" msgstr "primární" #: account/models.py:41 msgid "email addresses" msgstr "e-mailové adresy" #: account/models.py:150 msgid "created" msgstr "vytvořeno" #: account/models.py:151 msgid "sent" msgstr "odeslaný" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "klíč" #: account/models.py:157 msgid "email confirmation" msgstr "Potvrzovací e-mail" #: account/models.py:158 msgid "email confirmations" msgstr "Ověřovací e-maily" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Nelze přidat e-mailovou adresu k účtu chráněnému dvoufaktorovouautentizací." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Dvoufaktorové ověřování nelze deaktivovat." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Nelze generovat kódy pro obnovení bez aktivovaného dvoufaktorového ověřování." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Nemůžete aktivovat dvoufaktorovou autentizaci, dokud nepotvrdíte svoue-" "mailovou adresu." #: mfa/adapter.py:141 msgid "Master key" msgstr "Hlavní klíč" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Záložní klíč" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Klíč #{number}" #: mfa/apps.py:9 msgid "MFA" msgstr "2FA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Záchranné kódy" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP Autentifikátor" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Kód autentifikátoru" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Bez hesla" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Povolení možnosti bez hesla vám umožní přihlásit se pouze pomocí tohoto " "klíče, ale klade další požadavky, jako je biometrie nebo ochrana PIN." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Účet s touto e-mailovou adresou již existuje. Prosím přihlaste se nejdříve " "pod tímto účtem a potom připojte svůj %s účet." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Neplatný token." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Váš účet nemá nastavené heslo." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Váš účet nemá žádný ověřený e-mail." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Nemůžete odpojit svůj poslední externí účet." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Externí účet je již spojen s jiným účtem." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Účty sociálních sítí" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "poskytovatel" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID poskytovatele" #: socialaccount/models.py:56 msgid "name" msgstr "jméno" #: socialaccount/models.py:58 msgid "client id" msgstr "id klienta" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID nebo uživatelský klíč" #: socialaccount/models.py:63 msgid "secret key" msgstr "tajný klíč" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "tajný API klíč, tajný klientský klíč nebo uživatelský tajný klíč" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Klíč" #: socialaccount/models.py:81 msgid "social application" msgstr "sociální aplikace" #: socialaccount/models.py:82 msgid "social applications" msgstr "sociální aplikace" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "poslední přihlášení" #: socialaccount/models.py:120 msgid "date joined" msgstr "datum registrace" #: socialaccount/models.py:121 msgid "extra data" msgstr "extra data" #: socialaccount/models.py:125 msgid "social account" msgstr "účet sociální sítě" #: socialaccount/models.py:126 msgid "social accounts" msgstr "účty sociálních sítí" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) nebo přístupový token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "tajný token" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) nebo token pro obnovu (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "vyprší" #: socialaccount/models.py:174 msgid "social application token" msgstr "token sociální aplikace" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokeny sociálních aplikací" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Neplatná data profilu" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Přihlášení" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Zrušit" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Chyba při odesílání požadavku: \"%s\". Odpoveď byla: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Chyba při získávání přístupového klíče od \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Není uložen žádný požadavkový klíč pro: \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Není uložen žádný přístupový klíč pro: \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Není přístup k privátním zdrojům: \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Chyba při získávání požadavkového klíče \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Neaktivní účet" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Tento účet není aktivní." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Potvrdit přístup" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Pro ochranu účtu se prosím znovu ověřte." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Alternativní možnosti" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "Ověření e-mailu" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Zadejte ověřovací kód e-mailu" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Na adresu %(email_link)s jsme poslali ověřovací kód. Jeho platnost brzy " "vyprší, zadejte ho prosím včas." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Potvrdit" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Přihlásit se" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Zadejte Ověřovací Kód" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-mailové adresy" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "K vašemu účtu jsou přiřazeny tyto e-mailové adresy:" #: templates/account/email.html:25 msgid "Verified" msgstr "Ověřeno" #: templates/account/email.html:29 msgid "Unverified" msgstr "Neověřeno" #: templates/account/email.html:34 msgid "Primary" msgstr "Primární" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Zvolit jako primární" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Znovu zaslat oveřovací e-mail" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Odstranit" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Přidat e-mailovou adresu" #: templates/account/email.html:70 msgid "Add Email" msgstr "Přidat e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Opravdu chcete odstranit zvolené e-mailové adresy?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Tento e-mail jste obdrželi, protože vy nebo někdo jiný se pokusil " "registrovat účet s \n" "použitím e-mailové adresy:\n" "\n" "%(email)s\n" "\n" "Ale účet s touto e-mailovou adresou již existuje. Pokud jste na to " "zapomněli, \n" "použijte prosím postup obnovení hesla k obnovení vašeho účtu:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Účet již existuje" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Pozdrav z %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Děkujeme, že používáte %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Tento e-mail jste obdrželi, protože ve vašem účtu byla provedena následující " "změna:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Pokud tuto změnu nepoznáváte, prosím okamžitě proveďte náležitá bezpečnostní " "opatření. Změna vašeho účtu pochází z:\n" "\n" "- IP adresa: %(ip)s\n" "- Prohlížeč: %(user_agent)s\n" "- Datum %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Váš e-mail byl změněn z %(from_email)s na %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Email změněn" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Váš email byl potvrzen." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Potvrzení E-mailu" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Tento e-mail jste obdrželi protože uživatel %(user_display)s zadal vaši e-" "mailovou adresu k registraci účtu na stránkách %(site_domain)s." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Níže najdete váš ověřovací kód. Zadejte jej do otevřeného okna prohlížeče." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Pro potvrzení, že je to v pořádku, pokračujte na %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Potvrďte prosím svou e-mailovou adresu" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "E-mailová adresa %(deleted_email)s byla odstraněna z vašeho účtu." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Email odstraněn" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Níže najdete váš přihlašovací kód. Zadejte jej do otevřeného okna prohlížeče." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Tento e-mail může být bezpečně ignorován, pokud jste tuto akci nezahájili vy." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Přihlašovací kód" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Vaše heslo bylo změněno." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Heslo změněno" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Tento e-mail jste obdrželi protože jste vy nebo někdo jiný zažádal o změnu " "hesla uživatelského účtu.\n" "Pokud jste to nebyli vy, můžete tento e-mail ignorovat. Pokud ano, klikněte " "na odkaz níže pro změnu vašeho hesla." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "" "Pro případ, že byste zapomněli, vaše uživatelské jméno je %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail pro reset hesla" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Vaše heslo bylo obnoveno." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Reset hesla" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Vaše heslo bylo nastaveno." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Nastavení hesla" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Tento e-mail jste obdrželi, protože jste se vy nebo někdo jiný pokusili o " "přístup k účtu s e-mailem %(email)s. V naší databázi však žádný záznam o " "takovém účtu nemáme." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Pokud jste to byli vy, můžete si účet zaregistrovat pomocí odkazu níže." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Neznámý účet" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "E-mailové adresa" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Aktuální email" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Změněn na" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Vaše primární e-mailová adresa stále čeká na ověření." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Zrušit změnu" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Změnit na" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Změnit E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Potvrzení e-mailové adresy" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Prosím, potvrďte, že %(email)s je e-mailová " "adresa pro uživatele %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Nelze potvrdit %(email)s, protože již byl spojen s jiným účtem." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Tento ověřovací odkaz již vypršel nebo není správný. Prosím, zažádejte si o nový." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Pokud jste si ještě nevytvořili účet, nejprve se " "%(link)szaregistrujte%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Přihlaste se pomocí přístupového klíče" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Pošlete mi přihlašovací kód" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Odhlásit se" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Jste si jisti, že se chcete odhlásit?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Nemůžete odstranit primární e-mailovou adresu (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Ověření e-mailu posláno na %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Ověřili jste %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "E-mailová adresa %(email)s byla odebrána." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Úspěšně přihlášen jako %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Právě jste byl odhlášen." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Přihlašovací kód byl zaslán na adresu %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Heslo bylo úspěšně změněno." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Heslo bylo úspěšně nastaveno." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primární e-mail byla nastavena." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Změnit heslo" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Zapomenuté heslo?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Zapomněli jste heslo? Zadejte prosím svoji e-mailovou adresu a do e-mailové " "schránky Vám přijde návod na jeho obnovu." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Resetovat moje heslo" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Prosím, kontaktujte nás, pokud máte jakékoliv potíže s resetováním hesla." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Poslali jsme vám e-mail. Pokud jste ho neobdrželi, zkontrolujte prosím " "složku s nevyžádanou poštou (spam). V opačném případě nás kontaktujte, pokud " "ho neobdržíte do několika minut." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Chybný klíč" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Odkaz na resetování hesla byl neplatný, možná proto, že již byl použit. " "Požádejte prosím o nový reset hesla." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Vaše heslo je nyní změněno." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Nastavit heslo" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Zadejte své heslo:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "Obdržíte e-mail obsahující speciální kód pro přihlášení bez hesla." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Požádat kód" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Další možnosti přihlášení" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Zaregistrovat se" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Zaregistrovat se" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Máte již účet? %(link)sPřihlašte se%(end_link)s, prosím." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Zaregistrujte se pomocí přístupového klíče" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Registrace přístupového klíče" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Další možnosti" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registrace je uzavřena" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Omlouváme se, ale registrace je momentálně uzavřena." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Poznámka" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Již jste přihlášen jako %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Varování:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "V současné chvíli nemáte nastaveny žádné e-mailové adresy. Prosím, uložte si " "k účtu alespoň jeden e-mail, abyste moli dostávat upozornění nebo mohli " "použít funkci zapomenutého hesla apod." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Ověřte svoji e-mailovou adresu" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Byl vám zaslán ověřovací e-mail. Následujte odkaz v e-mailu pro dokončení " "registračního procesu. Pokud jste ho neobdrželi, zkontrolujte prosím složku " "s nevyžádanou poštou (spam). Neváhejte nás kontaktovat v případě, pokud e-" "mail do několika minut neobdržíte." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Tato část stránek vyžaduje ověření,\n" "že jste ten, kdo tvrdíte. K těmto účelům požadujeme\n" "aby jste ověřil vlastnictví své e-mailové adresy. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Zaslali jsme vám email pro oveření.\n" "Prosím, klikněte na odkaz uvnitř e-mailu. Pokud jste ho neobdrželi, " "zkontrolujte prosím složku s nevyžádanou poštou (spam).\n" "Neváhejte nás kontaktovat v případě, pokud e-mail nedostanete do několika " "minut." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Poznámka: stále můžete změnit " "vaši e-mailovou adresu.." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Zprávy:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Propojení účtu" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Dvoufaktorová autentizace" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Relace" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Váš účet je chráněn dvoufaktorovou autentizací. Prosím, zadejte autentizační " "kód:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "Byla vygenerována nová sada obnovovacích kódů dvoufaktorové autentizace." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Nové obnovovací kódy vygenerovány" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Autentifikátor byl aktivován." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Autentifikátor byl aktivován" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Autentifikátor byl deaktivován." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Autentifikátor byl deaktivován" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Byl přidán nový bezpečnostní klíč." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Bezpečnostní klíč přidán" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Bezpečnostní klíč byl odstraněn." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Bezpečnostní klíč odstraněn" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Autentifikátor" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Autentizace pomocí autentifikátoru je aktivní." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Autentifikátor není aktivní." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Deaktivovat" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Aktivovat" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Bezpečnostní klíče" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Přidali jste %(count)s bezpečnostní klíč." msgstr[1] "Přidali jste %(count)s bezpečnostní klíče." msgstr[2] "Přidali jste %(count)s bezpečnostního klíče." msgstr[3] "Přidali jste %(count)s bezpečnostních klíčů." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Nebyly přidány žádné bezpečnostní klíče." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Spravovat" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Přidat" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Záchranné kódy" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Z dostupných záchranných kódů je použit %(unused_count)s z celkového počtu " "%(total_count)s kódů." msgstr[1] "" "Z dostupných záchranných kódů jsou použity %(unused_count)s z celkového " "počtu %(total_count)s kódů." msgstr[2] "" "Z dostupných záchranných kódů je použito %(unused_count)s z celkového počtu " "%(total_count)s kódů." msgstr[3] "" "Z dostupných záchranných kódů je použitých %(unused_count)s z celkového " "počtu %(total_count)s kódů." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Nejsou nastaveny žádné záchranné kódy." #: templates/mfa/index.html:96 msgid "View" msgstr "Zobrazit" #: templates/mfa/index.html:102 msgid "Download" msgstr "Stáhnout" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Generovat" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Byla vygenerována nová sada záchranných kódů." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Bezpečnostní klíč přidán." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Bezpečnostní klíč odstraněn." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Zadejte ověřovací kód:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Chystáte se vygenerovat novou sadu obnovovacích kódů pro váš účet." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Tato akce zruší platnost vašich stávajících kódů." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Jste si jistý?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Nepoužité kódy" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Stáhnout kódy" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Generovat nové kódy" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Aktivovat Autentifikátor" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Chcete-li svůj účet chránit pomocí dvoufaktorového ověřování, naskenujte " "pomocí autentikační aplikace uvedený QR kód. Poté níže zadejte ověřovací kód " "vygenerovaný aplikací." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Klíč autentifikátoru" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Tento klíč můžete uložit a později použít k opětovné instalaci aplikace " "autentikátoru." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Deaktivovat Autentifikátor" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Chystáte se deaktivovat autentizaci pomocí autentifikátoru. Jste si jisti?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Přidat tajný klíč" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Odebrat tajný klíč" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Jste si jisti, že se chcete odebrat tajný klíč?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Použito" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Přístupový klíč" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Bezpečnostní klíč" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Tento klíč neoznačuje, zda se jedná o přístupový klíč." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Nespecifikováno" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Přidáno %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Naposledy použito %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Upravit" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Upravit bezpečnostní klíč" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Uložit" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "Vytvořte přístupový klíč" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" "Chystáte se vytvořit přístupový klíč pro svůj účet. Protože později můžete " "přidat další klíče, můžete klíče odlišit pomocí popisného názvu." #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "Vytvořit" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Tato funkce vyžaduje JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Přihlášení pomocí externího účtu selhalo" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Nastala chyba při přihlašování pomocí externího účtu." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Můžete se přihlásit pomocí jakéhokoliv následujícího externího účtu:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "V současné chvíli nemáte připojeny žádné další účty." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Přidejte další externí účet" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "K vašemu účtu byl připojen další účet od %(provider)s." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Externí účet přidán" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "Externí účet od %(provider)s byl odpojen od vašeho účtu." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Externí účet odpojen" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Připojit %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Chystáte se připojit nový externí účet od %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Přihlásit se pomocí %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "Chystáte se přihlásit pomocí externího účtu od %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Pokračovat" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Přihlášení zrušeno" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Rozhodli jste se zrušit přihlašování jednoho z vašich účtů. Pokud je to " "omylem, následujte přihlášení." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Externí účet byl připojen." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Externí účet byl odpojen." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Chystáte se použít vášeho %(provider_name)s účtu k přihlášení na naše " "stránky \n" "%(site_name)s. Jako poslední krok, prosím, vyplňte následující formulář:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Nebo použijte externí účet" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Odhlášen ze všech ostatních relací." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Začala v" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP adresa" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Prohlížeč" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Napoposledy použita v" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Aktuální" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Odhlásit ostatní relace" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Uživatelské relace" #: usersessions/models.py:92 msgid "session key" msgstr "klíč relace" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Propojení účtu" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Heslo musí obsahovat minimálně {0} znaků." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Tento e-mail jste obdrželi protože jste vy nebo někdo jiný zažádal o " #~ "změnu \n" #~ "hesla uživatelského účtu. Nicméně, nemáme žádný záznam o uživateli s \n" #~ "e-mailem %(email)s v naší databázi.\n" #~ "\n" #~ "Tento e-mail můžete bezpečně ignorovat, pokud jste nezažádali o změnu " #~ "hesla.\n" #~ "\n" #~ "Jestliže jste to byli vy, můžete se zaregistrovat na stránkách pomocí " #~ "odkazu \n" #~ "níže." #~ msgid "The following email address is associated with your account:" #~ msgstr "K vašemu účtu je přiřazena tato e-mailová adresa:" #~ msgid "Change Email Address" #~ msgstr "Změna e-mailové adresy" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "Pro zabezpečení vašeho účtu, prosím, zadejte vaše heslo:" #, fuzzy #~| msgid "Generate" #~ msgid "Regenerate" #~ msgstr "Generovat" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Přihlašte se prosím výběrem jednoho\n" #~ "z vašich účtů třetích stran. Nebo se zaregistruje na stránky %(site_name)s a " #~ "přihlašte se níže:" #~ msgid "or" #~ msgstr "nebo" #~ msgid "change password" #~ msgstr "změnit heslo" #~ msgid "OpenID Sign In" #~ msgstr "Přihlášení OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Tento e-mail je již přiřazen k jinému účtu." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Zaslali jsme vám e-mail. Prosím, kontaktujte nás, pokud ho nedostanete do " #~ "několika minut." #~| msgid "The password reset token was invalid." #~ msgid "The provided password is not valid." #~ msgstr "Použité heslo není platné." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Zadané přihlašovací údaje nejsou správné." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Uživatelské jméno může obsahovat pouze písmena, číslice a znaky @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Toto uživatelské jméno je již zvoleno. Prosím, vyberte si jiné." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Přihlásit se" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Potvrdili jste e-mailovou adresu %(email)s uživateli %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "Děkujeme za využívání našich stránek!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Ověřovací e-mail byl zaslán: %(email)s" #~ msgid "Delete Password" #~ msgstr "Smazat heslo" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "Můžete si smazat heslo, protože používáte jiné způsoby přihlášení." #~ msgid "delete my password" #~ msgstr "Odstanit moje heslo" #~ msgid "Password Deleted" #~ msgstr "Heslo bylo odstraněno" django-allauth-65.0.2/allauth/locale/da/000077500000000000000000000000001467545753200177755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/da/LC_MESSAGES/000077500000000000000000000000001467545753200215625ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/da/LC_MESSAGES/django.po000066400000000000000000001460201467545753200233670ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:40+0200\n" "Last-Translator: b'Tuk Bredsdorff '\n" "Language-Team: \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.1.1\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Denne konto er i øjeblikket inaktiv." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Du kan ikke fjerne din primære emailadresse (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Denne emailadresse er allerede knyttet til denne konto." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Den angivne emailadresse og/eller adgangskode er ikke korrekt." #: account/adapter.py:61 #, fuzzy #| msgid "A user is already registered with this address." msgid "A user is already registered with this email address." msgstr "En bruger er allerede registreret med denne emailadresse." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Indtast din nuværende adgangskode." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Nuværende adgangskode" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Ugyldigt token" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Token for nulstilling af adgangskode var ugyldig." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Din konto har ikke nogen bekræftet emailadresse." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Der er for mange mislykkede logonforsøg. Prøv igen senere." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Emailadressen er ikke tildelt til nogen brugerkonto" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Din primære emailadresse skal bekræftes." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Brugernavn kan ikke bruges. Brug venligst et andet brugernavn." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Det angivne brugernavn og/eller adgangskoden er ikke korrekt." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Glemt password?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "token hemmelighed" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "hemmelig nøgle" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Din primære emailadresse skal bekræftes." #: account/apps.py:11 msgid "Accounts" msgstr "Konti" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Du skal skrive den samme adgangskode hver gang." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Adgangskode" #: account/forms.py:93 msgid "Remember Me" msgstr "Husk mig" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Emailadresse" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Email" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Brugernavn" #: account/forms.py:123 msgid "Username or email" msgstr "Brugernavn eller email" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Bruger" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Glemt password?" #: account/forms.py:299 msgid "Email (again)" msgstr "Email (igen)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Bekræftelse af emailadresse" #: account/forms.py:311 msgid "Email (optional)" msgstr "Email (valgfri)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Du skal skrive den samme emailadresse hver gang." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Adgangskode (igen)" #: account/forms.py:554 msgid "Current Password" msgstr "Nuværende adgangskode" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Ny adgangskode" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Ny adgangskode (igen)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "bruger" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "emailadresse" #: account/models.py:34 msgid "verified" msgstr "bekræftet" #: account/models.py:35 msgid "primary" msgstr "primær" #: account/models.py:41 msgid "email addresses" msgstr "emailadresser" #: account/models.py:150 msgid "created" msgstr "oprettet" #: account/models.py:151 msgid "sent" msgstr "sendt" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "nøgle" #: account/models.py:157 msgid "email confirmation" msgstr "emailbekræfelse" #: account/models.py:158 msgid "email confirmations" msgstr "emailbekræftelse" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "hemmelig nøgle" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Adgangskode" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "En konto med denne emailadresse eksisterer allerede. Log venligst ind med " "den konto først og tilknyt din %s konto derefter." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Ugyldigt token" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Der er ikke oprettet noget password til din konto." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Din konto har ikke nogen bekræftet emailadresse." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "Du kan logge ind med følgende tredjepartskonti:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Den sociale konto er allerede tilknyttet en anden konto." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sociale konti" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "udbyder" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "udbyder" #: socialaccount/models.py:56 msgid "name" msgstr "navn" #: socialaccount/models.py:58 msgid "client id" msgstr "klient id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID, eller konsumer nøgle" #: socialaccount/models.py:63 msgid "secret key" msgstr "hemmelig nøgle" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API hemmelighed, klient hemmelighed eller konsumet hemmelighed" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Nøgle" #: socialaccount/models.py:81 msgid "social application" msgstr "social applikation" #: socialaccount/models.py:82 msgid "social applications" msgstr "sociale applikationer" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "sidste log ind" #: socialaccount/models.py:120 msgid "date joined" msgstr "dato oprettet" #: socialaccount/models.py:121 msgid "extra data" msgstr "ekstra data" #: socialaccount/models.py:125 msgid "social account" msgstr "social konto" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sociale konti" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "“oauth_token” (OAuth1) eller adgangstoken (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token hemmelighed" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "“oauth_token_secret” (OAuth1) eller fornyelsestoken (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "udløber den" #: socialaccount/models.py:174 msgid "social application token" msgstr "socialt applikationstoken" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "sociale applikationstokener" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Ugyldig profildata" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Bruger" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Ugyldig respons under forsøg på at hente request token fra “%s”." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Ugyldig respons under forsøg på at hente adgangstoken fra “%s”." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Intet request token gemt for “%s”." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Intet adgangstoken gemt for “%s”." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Ingen adgang til private ressourcer på “%s”." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Ugyldig respons under forsøg på at hente request token fra “%s”." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Inaktiv konto" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Denne konto er inaktiv." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Bekræft venligst din emailadresse" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "emailbekræfelse" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "token hemmelighed" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Bekræft" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Log ind" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Emailadresser" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "De følgende emailadresser er tilknyttet din konto:" #: templates/account/email.html:25 msgid "Verified" msgstr "Bekæftet" #: templates/account/email.html:29 msgid "Unverified" msgstr "Ubekræftet" #: templates/account/email.html:34 msgid "Primary" msgstr "Primær" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Gør primær" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Send bekræftelse igen" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Fjern" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Tilføj emailadresse" #: templates/account/email.html:70 msgid "Add Email" msgstr "Tilføj email" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Vil du virkelig fjerne den valgte emailadresse?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "Tak fra %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Tak fordi du bruger %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Emailadresse" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Du har bekræftet %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "emailbekræfelse" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s has given " #| "yours as an e-mail address to connect their account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Hej fra %(site_name)s!\n" "\n" "Du modtager denne email, fordi brugeren %(user_display)s ønsker at bruge den " "til sin konto.\n" "\n" "For at bekræfte dette, gå til %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Bekræft venligst din emailadresse" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Fjern" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Log ind" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Dit password er nu ændret." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Adgangskode (igen)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Hej fra %(site_name)s!\n" "\n" "Du har modtaget denne email fordi du eller en anden har bedt om et password " "til din konto.\n" "Den kan trygt ses bort fra, hvis du ikke har bedt om at få nulstillet dit " "password. Klik linket herunder for at nulstille dit password." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "I tilfælde af at du har glemt det er dit brugernavn %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Nulstilling af Password Email" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Dit password er nu ændret." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Nulstil password" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Dit password er nu ændret." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Nulstil password" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Konto" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Emailadresser" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Nuværende adgangskode" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Din primære emailadresse skal bekræftes." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Email" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Email" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Bekræft venligst din emailadresse" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Bekræft venligst at %(email)s er en e-mail " "adresse for %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Den sociale konto er allerede tilknyttet en anden konto." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Dette link til bekræftelse af email er udløbet eller ugyldigt. Lav venligst " "et nyt." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Hvis du ikke allerede har oprettet en konto, så %(link)sopret " "dig%(end_link)s først." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Log ud" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Er du sikker på, at du vil logge af?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Du kan ikke fjerne din primære emailadresse (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Bekræftelses-email sendt til %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Du har bekræftet %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Fjernede emailadressen %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Loggede succesfuldt ind med %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Du har logget ud." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Password ændret med success." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Password indstillet med success." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primær emailadresse indstillet." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Ændr password" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Glemt password?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Glemt dit password? Skriv din emailadresse herunder, og vi vil sende dig en " "email, hvorfra du kan nulstille det." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Nulstil mit password" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Kontakt os venligst, hvis du har problemer med at nulstille dit password." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Vi har sendt en email til dig for bekræftelse.\n" "Klik på linket i den. Kontakt os venligst, hvis du ikke modtager\n" " den i løbet af et par minutter." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Ugyldigt token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Linket til nulstilling af password var ugyldigt, muligvis fordi det allerede " "er blevet brugt. Lav venligst et nyt." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Dit password er nu ændret." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Indstil password" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Glemt password?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Opret" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Opret konto" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Har du allerede en konto? Så %(link)slog ind%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Opret konto" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Lukket for nye konti" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Vi beklager, men der er for tiden lukket for oprettelse af nye konti." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Note" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "du er allerede logget ind som %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Advarsel:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Du har på nuværende tidspunkt ikke nogen emailadresser tilknyttet. Du bør " "virkelig tilknytte en emailadresse, så du kan modtage notifikationer, " "resette dit password osv." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Bekræft din emailadresse" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Vi har sendt en email til dig. Følg linket i den for at færdiggøre " "oprettelsesprocessen. Kontakt os venligst, hvis du ikke modtager den i løbet " "af et par minutter." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Denne del af siden kræver, at du bekræfter, at\n" "du er hvem du påstår du er. Derfor er du nødt til at\n" "bekræfte, at du ejer din emailadresse " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Vi har sendt en email til dig for bekræftelse.\n" "Klik på linket i den. Kontakt os venligst, hvis du ikke modtager\n" " den i løbet af et par minutter." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Bemærk: du kan stadig ændre din " "emailadresse." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Kontoforbindelser" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "token hemmelighed" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "token hemmelighed" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Du har bekræftet %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "token hemmelighed" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "token hemmelighed" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "hemmelig nøgle" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "hemmelig nøgle" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Er du sikker på, at du vil logge af?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "hemmelig nøgle" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Ubekræftet" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "hemmelig nøgle" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Nuværende adgangskode" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "oprettet" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Social Network log ind-fejl" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Der opstod en fejl under forsøget på at logge ind via din social konto." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Du kan logge ind med følgende tredjepartskonti:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Du har ikke nogle social netværks-konti tilknyttet denne konto." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Tilføj tredjeparts konto" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Tilføj tredjeparts konto" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Tilføj tredjeparts konto" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Log ind afbrudt" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Du valgte at afbryde log ind på vores side med en af dine eksisterende " "konti. Hvis det var en fejl, så fortsæt venligst til log ind." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Den social konto er tilknyttet." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Tilknytningen til den social konto er blevet afbrydt." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Du er ved at bruge din %(provider_name)s -konto til at logge ind i\n" "%(site_name)s. Som et sidste skridt, udfyld venligst denne formular:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Emailadresser" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Nuværende adgangskode" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Kontoforbindelser" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Adgangskoden skal være på mindst {0} tegn." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Hej fra %(site_name)s!\n" #~ "\n" #~ "Du har modtaget denne email fordi du eller en anden har bedt om et " #~ "password til din konto.\n" #~ "Den kan trygt ses bort fra, hvis du ikke har bedt om at få nulstillet dit " #~ "password. Klik linket herunder for at nulstille dit password." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "De følgende emailadresser er tilknyttet din konto:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Bekræft venligst din emailadresse" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Log venligst ind med en\n" #~ "af dine eksisterende tredjeparts konti. Eller, opret\n" #~ "en konto på %(site_name)s og log ind herunder:" #~ msgid "or" #~ msgstr "eller" #~ msgid "change password" #~ msgstr "ændr password" #~ msgid "OpenID Sign In" #~ msgstr "OpenID Log ind" #~ msgid "This email address is already associated with another account." #~ msgstr "Denne emailadresse er allerede knyttet til en anden konto." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Vi har sendt dig en email. Kontakt os venligst, hvis du ikke modtager den " #~ "i løbet af et par minutter." django-allauth-65.0.2/allauth/locale/de/000077500000000000000000000000001467545753200200015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/de/LC_MESSAGES/000077500000000000000000000000001467545753200215665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/de/LC_MESSAGES/django.po000066400000000000000000001530161467545753200233760ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Jannis Vajen, 2013-2014 msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-21 14:26+0200\n" "Last-Translator: Natalia N \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.7.1-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Dieses Konto ist derzeit inaktiv." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Du kannst deine primäre E-Mail-Adresse nicht löschen." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Diese E-Mail-Adresse wird bereits in diesem Konto verwendet." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Die E-Mail-Adresse und/oder das Passwort sind leider falsch." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Es ist bereits jemand mit dieser E-Mail-Adresse registriert." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Bitte gib dein aktuelles Passwort ein." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Falscher Code." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Falsches Passwort." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Falsches oder abgelaufenes Token." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Das Sicherheits-Token zum Zurücksetzen des Passwortes war ungültig." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Du kannst nicht mehr als %d E-Mail-Adressen hinzufügen." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Zu viele gescheiterte Anmeldeversuche. Bitte versuche es später erneut." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Diese E-Mail-Adresse ist keinem Konto zugeordnet" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Deine primäre E-Mailadresse muss bestätigt werden." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Anmeldename kann nicht verwendet werden. Bitte wähle einen anderen Namen." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Der Anmeldename und/oder das Passwort sind leider falsch." #: account/adapter.py:741 msgid "Use your password" msgstr "Verwenden Sie Ihr Passwort" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Verwenden Sie eine Authentifizierungs-App oder einen Code" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Verwenden Sie einen Sicherheitsschlüssel" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Markierte E-Mail-Adressen als verifiziert kennzeichnen" #: account/apps.py:11 msgid "Accounts" msgstr "Konten" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Du musst zweimal das selbe Passwort eingeben." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Passwort" #: account/forms.py:93 msgid "Remember Me" msgstr "Angemeldet bleiben" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-Mail-Adresse" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-Mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Anmeldename" #: account/forms.py:123 msgid "Username or email" msgstr "Anmeldename oder E-Mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Anmeldung" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Passwort vergessen?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-Mail (wiederholen)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Bestätigung der E-Mail-Adresse" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-Mail (optional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Du musst zweimal dieselbe E-Mail-Adresse eingeben." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Passwort (Wiederholung)" #: account/forms.py:554 msgid "Current Password" msgstr "Aktuelles Passwort" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Neues Passwort" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Neues Passwort (Wiederholung)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Code" #: account/models.py:26 msgid "user" msgstr "Benutzer" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "E-Mail-Adresse" #: account/models.py:34 msgid "verified" msgstr "bestätigt" #: account/models.py:35 msgid "primary" msgstr "Primär" #: account/models.py:41 msgid "email addresses" msgstr "E-Mail-Adressen" #: account/models.py:150 msgid "created" msgstr "Erstellt" #: account/models.py:151 msgid "sent" msgstr "Gesendet" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "Schlüssel" #: account/models.py:157 msgid "email confirmation" msgstr "E-Mail-Bestätigung" #: account/models.py:158 msgid "email confirmations" msgstr "E-Mail-Bestätigungen" #: headless/apps.py:7 msgid "Headless" msgstr "Kopflos" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Sie können keine E-Mail-Adresse zu einem Konto hinzufügen, das durch die " "Zwei-Faktor-Authentifizierung geschützt ist." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Sie können die Zwei-Faktor-Authentifizierung nicht deaktivieren." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Sie können keine Wiederherstellungscodes generieren, ohne die Zwei-Faktor-" "Authentifizierung aktiviert zu haben." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Sie können die Zwei-Faktor-Authentifizierung nicht aktivieren, bis Sie Ihre " "E-Mail-Adresse verifiziert haben." #: mfa/adapter.py:141 msgid "Master key" msgstr "Hauptschlüssel" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Sicherungsschlüssel" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Schlüsselnr. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Wiederherstellungs-Codes" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP Authenticator" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Authentifizierungscode" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Passwortlos" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Wenn Sie den passwortlosen Betrieb aktivieren, können Sie sich nur mit " "diesem Schlüssel anmelden, müssen aber zusätzliche Anforderungen erfüllen, " "wie z. B. biometrische Daten oder PIN-Schutz." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Es existiert bereits ein Konto mit dieser E-Mail-Adresse. Bitte melde dich " "zuerst mit diesem Konto an, und verknüpfe es dann mit deinem %s-Konto." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Falsches Token." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Für dein Konto wurde noch kein Passwort festgelegt." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Dein Konto hat keine bestätigte E-Mail-Adresse." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Sie können Ihr letztes verbleibendes Drittanbieterkonto nicht trennen." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "" "Das Konto des Drittanbieters ist bereits mit einem anderen Konto dieser " "Seite verknüpft." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Konto" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "Anbieter" #: socialaccount/models.py:52 msgid "provider ID" msgstr "Anbieter-ID" #: socialaccount/models.py:56 msgid "name" msgstr "Name" #: socialaccount/models.py:58 msgid "client id" msgstr "Client-ID" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App-ID oder 'Consumer key'" #: socialaccount/models.py:63 msgid "secret key" msgstr "Geheimer Schlüssel" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "'API secret', 'client secret' oder 'consumer secret'" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Schlüssel" #: socialaccount/models.py:81 msgid "social application" msgstr "Soziale Anwendung" #: socialaccount/models.py:82 msgid "social applications" msgstr "Soziale Anwendungen" #: socialaccount/models.py:117 msgid "uid" msgstr "UID" #: socialaccount/models.py:119 msgid "last login" msgstr "Letzte Anmeldung" #: socialaccount/models.py:120 msgid "date joined" msgstr "Registrierdatum" #: socialaccount/models.py:121 msgid "extra data" msgstr "Weitere Daten" #: socialaccount/models.py:125 msgid "social account" msgstr "Soziales Konto" #: socialaccount/models.py:126 msgid "social accounts" msgstr "Soziale Konten" #: socialaccount/models.py:160 msgid "token" msgstr "Token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) oder \"access token\" (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "Geheimes Token" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) oder \"refresh token\" (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "Läuft ab" #: socialaccount/models.py:174 msgid "social application token" msgstr "Token für soziale Anwendung" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "Tokens für soziale Anwendungen" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Ungültige Profildaten" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Anmeldung" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Abbrechen" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Ungültige Antwort von \"%s\" als Anfrageschlüssel erbeten wurde. Die Antwort " "war: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Ungültige Antwort von \"%s\" als Zugangsschlüssel erbeten wurde." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Kein Request-Token gespeichert für \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Kein Access-Token gespeichert für \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Kein Zugriff zu privaten Daten auf \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Ungültige Antwort von \"%s\" als Anfrageschlüssel erbeten wurde." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Konto inaktiv" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Dieses Konto ist inaktiv." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Zugriff bestätigen" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Bitte authentifizieren Sie sich erneut, um Ihr Konto zu schützen." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Alternative Optionen" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "E-Mail-Verifizierung" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Geben Sie den E-Mail-Bestätigungscode ein" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Wir haben einen Code an %(email_link)s gesendet. Der Code läuft in Kürze ab, " "bitte geben Sie ihn bald ein." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Bestätigen" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Anmeldung" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Anmeldecode eingeben" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-Mail-Adressen" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Folgende E-Mail-Adressen sind mit diesem Konto verknüpft:" #: templates/account/email.html:25 msgid "Verified" msgstr "Bestätigt" #: templates/account/email.html:29 msgid "Unverified" msgstr "Unbestätigt" #: templates/account/email.html:34 msgid "Primary" msgstr "Primär" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Als primäre Adresse festlegen" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Bestätigungs-Mail nochmal verschicken" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Ausgewählte entfernen" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "E-Mail-Adresse hinzufügen" #: templates/account/email.html:70 msgid "Add Email" msgstr "E-Mail hinzufügen" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Möchtest du wirklich die ausgewählte E-Mail-Adresse entfernen?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Du erhältst diese E-Mail, weil du oder jemand anderes versucht hat, sich für " "ein Konto anzumelden mit E-Mail-Adresse:\n" "\n" "%(email)s\n" "\n" "Es existiert jedoch bereits ein Konto mit dieser E-Mail-Adresse. Falls du " "dies vergessen hast, verwende bitte das Passwort-Vergessen-Verfahren, um " "dein Konto wiederherzustellen:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Konto existiert bereits" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Hallo von %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Danke dass du %(site_name)s nutzt!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Sie erhalten diese E-Mail, weil die folgende Änderung an Ihrem Konto " "vorgenommen wurde:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Wenn Sie diese Änderung nicht erkennen, ergreifen Sie bitte umgehend " "angemessene Sicherheitsmaßnahmen. Die Änderung an Ihrem Konto stammt von:\n" "\n" "- IP-Adresse: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Datum: %(timestamp)s\"" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Ihre E-Mail wurde von %(from_email)s auf %(to_email)s geändert." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E-Mail geändert" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Ihre E-Mail wurde bestätigt." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "E-Mail-Bestätigung" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Sie erhalten diese E-Mail, weil Benutzer %(user_display)s Ihre E-Mail-" "Adresse angegeben hat, um ein Konto bei %(site_domain)s zu registrieren." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Ihr E-Mail-Verifizierungscode ist unten aufgeführt. Bitte geben Sie diese in " "Ihrem geöffneten Browserfenster ein." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Um zu bestätigen, dass dies korrekt ist, gehen Sie zu %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Bitte bestätige deine E-Mail-Adresse" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "Die E-Mail-Adresse %(deleted_email)s wurde aus Ihrem Konto entfernt." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "E-Mail entfernt" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Ihr Anmeldecode steht unten. Bitte geben Sie ihn in Ihrem geöffneten " "Browserfenster ein." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Diese E-Mail kann ignoriert werden, wenn Sie diese Aktion nicht initiiert " "haben." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Anmeldecode" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Dein Passwort wurde geändert." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Passwort geändert" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Du erhältst diese E-Mail weil du oder jemand anderes die Zurücksetzung des " "Passwortes für dein Konto gefordert hat.\n" "Falls es sich dabei nicht um dich handelt, kann diese Nachricht ignoriert " "werden. Rufe folgende Adresse auf um dein Passwort zurückzusetzen." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "" "Falls du deinen Anmeldenamen vergessen haben solltest; er lautet " "%(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-Mail zum Zurücksetzen des Passworts" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Ihr Passwort wurde zurückgesetzt." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Passwort zurücksetzen" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Ihr Passwort wurde festgelegt." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Passwort festgelegt" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Sie erhalten diese E-Mail, weil Sie oder jemand anderes versucht hat, auf " "ein Konto mit der E-Mail %(email)s zuzugreifen. Wir haben jedoch keinen " "solchen Account in unserer Datenbank gefunden." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Wenn es von Ihnen war, können Sie über den unten stehenden Link ein Konto " "erstellen." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Unbekanntes Konto" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Email-Adresse" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Aktuelle E-Mail" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Wechsel zu" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Deine E-Mail-Adresse steht immer noch aus und muss überprüft werden." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Änderung abbrechen" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Ändern zu" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Email ändern" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "E-Mail-Adresse bestätigen" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Bitte bestätige, dass %(email)s eine E-Mail-" "Adresse von %(user_display)s ist." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Kann %(email)s nicht bestätigen, da sie bereits von einem anderen Konto " "bestätigt wurde." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Dieser Bestätigungslink ist leider abgelaufen. Lass Dir bitte eine neue Bestätigungs-Mail schicken." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Du hast noch kein Konto bei uns? Dann %(link)serstelle%(end_link)s bitte " "zunächst eins." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Mit einem Passkey anmelden" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Anmeldecode senden" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Abmelden" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Bist du sicher, dass du dich abmelden möchtest?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Du kannst deine primäre E-Mail-Adresse (%(email)s) nicht löschen." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Bestätigungs-E-Mail wurde an %(email)s verschickt." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Du hast die Adresse %(email)s bestätigt." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "E-Mailadresse %(email)s entfernt." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Erfolgreich als %(name)s angemeldet." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Du hast dich abgemeldet." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Ein Anmeldecode wurde an %(email)s gesendet." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Das Passwort wurde geändert." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Das Passwort wurde erfolgreich gesetzt." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primäre E-Mailadresse festgelegt." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Passwort ändern" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Passwort vergessen?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Passwort vergessen? Gib deine E-Mail-Adresse unten ein, dann schicken wir " "dir einen Link, unter dem du dein Passwort zurücksetzen kannst." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Passwort zurücksetzen" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Bitte kontaktiere uns, wenn das Zurücksetzen des Passworts nicht klappt." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Wir haben Dir eine E-Mail geschickt. Wenn du die E-Mail nicht in deinem " "Posteingang siehst, überprüfe bitte deinen Spam-Ordner. Wenn die E-Mail " "ansonsten nicht in ein paar Minuten angekommen ist, gib uns bitte Bescheid." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Falsches Token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Der Link zum Zurücksetzen des Passworts war ungültig, womöglich wurde dieser " "Link bereits benutzt. Bitte lass dein Passwort noch mal zurücksetzen." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Dein Passwort wurde geändert." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Passwort setzen" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Geben Sie Ihr Passwort ein:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Sie erhalten eine E-Mail mit einem speziellen Code für eine anmeldungsfreie " "Anmeldung." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Code anfordern" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Andere Anmeldeoptionen" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registrieren" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registrieren" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "Du hast bereits ein Konto bei uns? Dann bitte %(link)shier " "entlang%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Mit einem Passkey registrieren" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Passkey Registrierung" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Andere Optionen" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registrierung geschlossen" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Es tut uns leid, aber die Registrierung ist derzeit geschlossen." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Anmerkung" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Du bist bereits als %(user_display)s angemeldet." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Warnung:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Du hast derzeit keine E-Mail-Adressen angegeben. Das solltest du allerdings " "tun, denn nur so können wir dich benachrichtigen und dein Passwort " "zurücksetzen." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Bestätige deine E-Mail-Adresse" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Wir haben dir eine E-Mail geschickt, um deine Adresse zu verifizieren. Bitte " "folge dem Link in der E-Mail um den Anmeldeprozess abzuschließen. Wenn du " "die E-Mail nicht in deinem Posteingang siehst, überprüfe bitte deinen Spam-" "Ordner. Wenn die E-Mail nicht in ein paar Minuten angekommen ist, gib uns " "bitte Bescheid." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Auf diesem Teil der Webseite möchten wie sichergehen,\n" "dass du die Person bist für die du dich ausgibst.\n" "Dazu musst du deine E-Mail-Adresse verifizieren. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Wir haben Dir eine E-Mail geschickt, um deine\n" "Adresse zu verifizieren. Bitte klick auf den Link\n" "in der E-Mail. Wenn du die E-Mail nicht in deinem Posteingang siehst, " "überprüfe bitte deinen Spam-Ordner. Wenn die E-Mail ansonsten nicht in ein " "paar Minuten angekommen ist, gib uns bitte Bescheid." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Anmerkung: Du kannst Deine E-Mail-" "Adresse ändern." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Nachrichten:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menü" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Konto-Verknüpfungen" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Zwei-Faktor-Authentifizierung" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sitzungen" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Ihr Konto ist durch Zwei-Faktor-Authentifizierung geschützt. Bitte geben Sie " "einen Authenticator-Code ein:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Ein neuer Satz Wiederherstellungscodes wurde generiert." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Neue Wiederherstellungscodes generiert" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Authenticator-App aktiviert." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Authenticator-App aktiviert" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Authenticator-App deaktiviert." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Authenticator-App deaktiviert" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Es wurde ein neuer Sicherheitsschlüssel hinzugefügt." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Sicherheitsschlüssel hinzugefügt" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Ein Sicherheitsschlüssel wurde entfernt." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Sicherheitsschlüssel entfernt" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Authenticator-App" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Die Authentifizierung mit einer Authenticator-App ist aktiv." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Es ist keine Authenticator-App aktiv." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Deaktivieren" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Aktivieren" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Sicherheitsschlüssel" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Sie haben %(count)s Sicherheitsschlüssel hinzugefügt." msgstr[1] "Sie haben %(count)s Sicherheitsschlüssel hinzugefügt." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Es wurden keine Sicherheitsschlüssel hinzugefügt." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Verwalten" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Hinzufügen" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Wiederherstellungs-Codes" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Es steht %(unused_count)s von %(total_count)s Wiederherstellungscodes zur " "Verfügung." msgstr[1] "" "Es stehen %(unused_count)s von %(total_count)s Wiederherstellungscodes zur " "Verfügung." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Es wurden keine Wiederherstellungscodes eingerichtet." #: templates/mfa/index.html:96 msgid "View" msgstr "Anzeigen" #: templates/mfa/index.html:102 msgid "Download" msgstr "Herunterladen" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Generieren" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Ein neuer Satz Wiederherstellungscodes wurde generiert." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Sicherheitsschlüssel hinzugefügt." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Sicherheitsschlüssel entfernt." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Geben Sie einen Authentifizierungscode ein:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Du bist dabei, einen neuen Satz Wiederherstellungscodes für Ihr Konto zu " "generieren." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Diese Aktion wird Ihre vorhandenen Codes ungültig machen." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Sind Sie sicher?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Unbenutzte Codes" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Codes herunterladen" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Neue Codes generieren" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Authenticator-App aktivieren" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Um Ihr Konto mit der Zwei-Faktor-Authentifizierung zu schützen, scannen Sie " "den unten stehenden QR-Code mit Ihrer Authenticator-App. Geben Sie dann den " "von der App generierten Bestätigungscode unten ein." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Authentifizierungsgeheimnis" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Sie können dieses Geheimnis speichern und zu einem späteren Zeitpunkt " "verwenden, um Ihre Authenticator-App neu zu installieren." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Authenticator-App deaktivieren" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Du bist dabei, die Authentifizierung per Authenticator-App zu deaktivieren. " "Sind Sie sicher?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Sicherheitsschlüssel hinzufügen" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Sicherheitsschlüssel entfernen" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "" "Sind Sie sicher, dass Sie diesen Sicherheitsschlüssel entfernen möchten?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Verwendung" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Passkey" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Sicherheitsschlüssel" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Dieser Schlüssel gibt nicht an, ob es sich um einen Passkey handelt." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Unbestimmt" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Hinzugefügt um %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Zuletzt verwendet %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Bearbeiten" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Sicherheitsschlüssel bearbeiten" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Speichern" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "Passkey erstellen" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "Sie sind dabei, einen Passkey für Ihr Konto zu erstellen. Da Sie später weitere Schlüssel hinzufügen können, können Sie einen beschreibenden Namen verwenden, um die Schlüssel voneinander zu unterscheiden." #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "Erstellen" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Diese Funktionalität erfordert JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Drittanbieter-Anmeldefehler" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Beim Versuch, sich über Ihr Drittanbieterkonto anzumelden, ist ein Fehler " "aufgetreten." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Sie können sich bei Ihrem Konto mit einem der folgenden Drittanbieter-Konten " "anmelden:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Derzeit sind keine Drittanbieterkonten mit diesem Konto verbunden." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Einen Drittanbieter-Account hinzufügen" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "Ein Drittanbieterkonto von %(provider)s wurde mit Ihrem Konto verbunden." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Drittanbieterkonto verbunden" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "Ein Drittanbieterkonto von %(provider)s wurde von Ihrem Konto getrennt." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Drittanbieterkonto getrennt" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Mit %(provider)s verbinden" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Du bist dabei, ein neues Drittanbieter-Konto von %(provider)s zu verknüpfen." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Anmelden über %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "Du bist dabei, dich mit einem Konto von %(provider)s anzumelden." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Fortfahren" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Anmeldung abgebrochen" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Du hast die Anmeldung abgebrochen. Wenn das nur ein Versehen oder ein Fehler " "war, folge bitte diesem Link um dich " "anzumelden." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Konten wurden erfolgreich verknüpft." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Das Drittanbieterkonto wurde getrennt." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Du verwendest dein %(provider_name)s-Konto, um dich bei\n" "%(site_name)s anzumelden. Zum Abschluss bitte das folgende Formular " "ausfüllen:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Oder Drittanbieter verwenden" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Von allen anderen Sitzungen abgemeldet." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Gestartet um" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP-Adresse" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Browser" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Zuletzt gesehen um" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Aktuell" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Andere Sitzungen abmelden" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Benutzersitzungen" #: usersessions/models.py:92 msgid "session key" msgstr "Sitzungsschlüssel" #~ msgid "Account Connection" #~ msgstr "Konto-Verknüpfung" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Das Passwort muss aus mindestens {0} Zeichen bestehen." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Du erhältst diese E-Mail weil du oder jemand anderes die Zurücksetzung " #~ "des Passwortes für dein Konto gefordert hat. Wir haben jedoch keinen " #~ "Eintrag eines Benutzers mit der E-Mail-Adresse %(email)s in unserer " #~ "Datenbank.\n" #~ "\n" #~ "Falls es sich dabei nicht um dich handelt, kann diese Nachricht ignoriert " #~ "werden.\n" #~ "\n" #~ "Ansonsten kannst du dich über den unten stehenden Link für ein Konto " #~ "anmelden." #~ msgid "The following email address is associated with your account:" #~ msgstr "Die folgende Email-Adresse ist mit Ihrem Konto verknüpft:" #~ msgid "Change Email Address" #~ msgstr "E-Mail-Adresse ändern" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "" #~ "Um die Sicherheit Ihres Kontos zu gewährleisten, geben Sie bitte Ihr " #~ "Passwort ein:" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Bitte melde dich mit einem der folgenden Netzwerkkonten an, oder registriere dich auf %(site_name)s, dann " #~ "kannst du dich unten mit deinem Konto anmelden:" #~ msgid "or" #~ msgstr "oder" #~ msgid "change password" #~ msgstr "Passwort ändern" #~ msgid "OpenID Sign In" #~ msgstr "OpenID-Anmeldung" #~ msgid "This email address is already associated with another account." #~ msgstr "Diese E-Mail-Adresse wird bereits in einem anderen Konto verwendet." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Wir haben Dir eine E-Mail geschickt. Bitte kontaktiere uns, wenn du sie " #~ "nicht in ein paar Minuten erhalten hast." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Die Anmeldedaten sind leider falsch." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Anmeldenamen dürfen nur Buchstaben und Ziffern und folgende Zeichen " #~ "enthalten: @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Der Anmeldename ist bereits vergeben – bitte wähle einen anderen." #, fuzzy #~ msgid "Shopify Sign In" #~ msgstr "Anmeldung" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Du hast bestätigt, dass %(email)s eine " #~ "gültige Adresse von %(user_display)s ist." #~ msgid "Thanks for using our site!" #~ msgstr "Danke, dass du unsere Seite nutzt!" django-allauth-65.0.2/allauth/locale/el/000077500000000000000000000000001467545753200200115ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/el/LC_MESSAGES/000077500000000000000000000000001467545753200215765ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/el/LC_MESSAGES/django.po000066400000000000000000001666011467545753200234120ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:38+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Αυτός ο λογαριασμός είναι ανενεργός." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Δεν μπορείτε να αφαιρέσετε την πρωτεύον διεύθυνση email (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Αυτό το e-mail χρησιμοποιείται ήδη από αυτό το λογαριασμό." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Η διέυθυνση e-mail ή/και το συνθηματικό που δόθηκαν δεν είναι σωστά." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Υπάρχει ήδη εγγεγραμμένος χρήστης με αυτό το e-mail." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Παρακαλώ γράψτε το τρέχον συνθηματικό σας." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Τρέχον συνθηματικό" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Μη-έγκυρο Κουπόνι" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Το κουπόνι επαναφοράς του συνθηματικού δεν ήταν έγκυρο." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Δεν έχει επιβεβαιωθεί κανένα e-mail του λογαριασμού σας." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Πολλές αποτυχημένες προσπάθειες σύνδεσης. Προσπαθήστε ξανά αργότερα." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Το e-mail δεν χρησιμοποιείται από κανέναν λογαριασμό" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Η πρωτεύον διεύθυνση e-mail πρέπει να επιβεβαιωθεί." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Δεν μπορεί να χρησιμοποιηθεί αυτό το όνομα χρήστη. Δοκιμάστε άλλο." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Το όνομα χρήστη ή/και το συνθηματικό που δόθηκαν δεν είναι σωστά." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Ξέχασα το συνθηματικό μου" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "token secret" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "μυστικό κλειδί" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Η πρωτεύον διεύθυνση e-mail πρέπει να επιβεβαιωθεί." #: account/apps.py:11 msgid "Accounts" msgstr "Λογαριασμοί" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Πρέπει να δοθεί το ίδιο συνθηματικό κάθε φορά." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Συνθηματικό" #: account/forms.py:93 msgid "Remember Me" msgstr "Αυτόματη Σύνδεση" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Διεύθυνση e-mail" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Όνομα χρήστη" #: account/forms.py:123 msgid "Username or email" msgstr "Όνομα χρήστη ή e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Σύνδεση" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Ξέχασα το συνθηματικό μου" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "E-mail (επιβεβαίωση)" #: account/forms.py:303 #, fuzzy #| msgid "email confirmation" msgid "Email address confirmation" msgstr "Επιβεβαίωση διεύθυνσης e-mail" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (προαιρετικό)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Πρέπει να δοθεί το ίδιο email κάθε φορά." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Συνθηματικό (επιβεβαίωση)" #: account/forms.py:554 msgid "Current Password" msgstr "Τρέχον συνθηματικό" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Νέο συνθηματικό" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Νέο συνθηματικό (επιβεβαίωση)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "χρήστης" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "διεύθυνση e-mail" #: account/models.py:34 msgid "verified" msgstr "επαληθευμένο" #: account/models.py:35 msgid "primary" msgstr "πρωτεύον" #: account/models.py:41 msgid "email addresses" msgstr "διευθύνσεις e-mail" #: account/models.py:150 msgid "created" msgstr "δημιουργήθηκε" #: account/models.py:151 msgid "sent" msgstr "απστάλει" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "κλειδί" #: account/models.py:157 msgid "email confirmation" msgstr "e-mail επιβεβαίωσης" #: account/models.py:158 msgid "email confirmations" msgstr "e-mail επιβεβαίωσης" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "μυστικό κλειδί" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Συνθηματικό" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Υπάρχει ήδη ένας λογαριασμός με αυτό το e-mail. Συνδεθείτε πρώτα με αυτόνκαι " "μετά συνδέστε τον λογαριασμό %s." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Μη-έγκυρο Κουπόνι" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Δεν έχει οριστεί συνθηματικό στον λογαριασμό σας." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Δεν έχει επιβεβαιωθεί κανένα e-mail του λογαριασμού σας." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Μπορείτε να συνδεθείτε στον λογαριασμό σας με οποιοδήποτε από τους παρακάτω " "εξωτερικούς λογαριασμούς:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "" "Ο λογαριασμός κοινωνικών μέσων είναι ήδη συνδεδεμένος με διαφορετικό " "λογαριασμό." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Λογαριασμοί Κοινωνικών Μέσων" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "πάροχος" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "πάροχος" #: socialaccount/models.py:56 msgid "name" msgstr "όνομα" #: socialaccount/models.py:58 msgid "client id" msgstr "id πελάτη" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID ή consumer key(κλειδί καταναλωτή)" #: socialaccount/models.py:63 msgid "secret key" msgstr "μυστικό κλειδί" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API secret, client secret, ή consumer secret" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Κλειδί" #: socialaccount/models.py:81 msgid "social application" msgstr "εφαρμογή κοινωνικών μέσων" #: socialaccount/models.py:82 msgid "social applications" msgstr "εφαρμογές κοινωνικών μέσων" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "τελευταία σύνδεση" #: socialaccount/models.py:120 msgid "date joined" msgstr "ημερομηνία εγγραφής" #: socialaccount/models.py:121 msgid "extra data" msgstr "έξτρα δεδομένα" #: socialaccount/models.py:125 msgid "social account" msgstr "λογαριασμός κοινωνικών μέσων" #: socialaccount/models.py:126 msgid "social accounts" msgstr "λογαριασμοί κοινωνικών μέσων" #: socialaccount/models.py:160 msgid "token" msgstr "κουπόνι" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ή access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token secret" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ή refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "λήγει στις" #: socialaccount/models.py:174 msgid "social application token" msgstr "token (κουπόνι) εφαρμογής κοινωνικών μέσων" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokens (κουπόνια) εφαρμογής κοινωνικών μέσων" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Άκυρα δεδομένα προφίλ" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Σύνδεση" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Μη-έγκυρη απάντηση κατά την απόκτηση κουπονιού αιτήματος από \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Μη-έγκυρη απάντηση κατά την απόκτηση κουπονιού πρόσβασης από \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Δεν υπάρχει αποθηκευμένο κουπόνι αιτήματος για \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Δεν υπάρχει αποθηκευμένο κουπόνι πρόσβασης για \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Αδύνατη πρόσβαση σε ιδιοτικούς πόρους στο \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Μη-έγκυρη απάντηση κατά την απόκτηση κουπονιού αιτήματος από \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Λογαριασμός Ανενεργός" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Αυτός ο λογαριασμός είναι ανενεργός." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Επιβεβαίωση διεύθυνση e-mail" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "e-mail επιβεβαίωσης" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "token secret" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Επιβεβαίωση" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Σύνδεση" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Διεύθυνση e-mail" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "" "Οι διευθύνσεις e-mail που ακολουθούν είναι συσχετισμένες με τον λογαριασμό " "σας:" #: templates/account/email.html:25 msgid "Verified" msgstr "Εγκεκριμένος" #: templates/account/email.html:29 msgid "Unverified" msgstr "Μη-επιβεβαιωμένο" #: templates/account/email.html:34 msgid "Primary" msgstr "Πρωτεύον" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Ορισμός ως Πρωτεύον" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Επανάληψη αποστολής Επαλήθευσης" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Αφαίρεση" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Προσθήκη διέυθυνσης e-mail" #: templates/account/email.html:70 msgid "Add Email" msgstr "Προσθήκη e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Θέλετε να αφαιρέσετε την επλεγμένη διεύθυνση e-mail?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "Ευχαριστούμε από το %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Ευχαριστούμε που χρησιμοποιήσατε το %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Διεύθυνση e-mail" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Έχετε επιβεβαιώσει το %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "e-mail επιβεβαίωσης" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s has given " #| "yours as an e-mail address to connect their account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Χαιρετίσματα από το %(site_name)s!\n" "\n" "Λαμβάνετε αυτό το e-mail επειδή ο χρήστης %(user_display)s έκανε αίτηση " "σύνδεσης της διέυθυνσης e-mail σας με τον λογαριασμό του.\n" "\n" "Για να επιβεβαιώσετε αυτή την ενέργεια, πηγαίνετε στο %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Παρακαλούμε να επιβεβαιώσετε την διεύθυνση e-mail σας" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Αφαίρεση" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Σύνδεση" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Το συνθηματικό σας έχει αλλάξει." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Συνθηματικό (επιβεβαίωση)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Χαιρετίσματα από το %(site_name)s!\n" "\n" "Λαμβάνετε αυτό το e-mail επειδή εσείς ή κάποιος άλλος έχει κάνει αίτηση " "συνθηματικού για τον λογαριασμό σας.\n" "Αν δεν ζητήσατε επαναφορά συνθηματικού, μπορεί να αγνοηθεί με ασφάλεια. " "Πατήστε στον σύνδεσμο που ακολουθεί για να επαναφέρετε το συνθηματικό σας." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Σε περίπτωση που ξεχάσατε, το όνομα χρήστη σας είναι %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail επαναφοράς συνθηματικού" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Το συνθηματικό σας έχει αλλάξει." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Επαναφορά Συνθηματικού" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Το συνθηματικό σας έχει αλλάξει." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Επαναφορά Συνθηματικού" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Λογαριασμός" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Διεύθυνση e-mail" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Τρέχον συνθηματικό" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Η πρωτεύον διεύθυνση e-mail πρέπει να επιβεβαιωθεί." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Επιβεβαίωση διεύθυνση e-mail" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Παρακαλούμε επιβεβαιώστε ότι το %(email)s " "αποτελεί διεύθυνση e-mail για τον χρήστη %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Ο λογαριασμός κοινωνικών μέσων είναι ήδη συνδεδεμένος με διαφορετικό " "λογαριασμό." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Αυτός ο σύνδεσμος επιβεβαίωσης έχει λήξει ή δεν είναι έγκυρος. Παρακαλούμε " "κάντε καινούρια αίτηση επιβεβαίωσης e-mail." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Αν δεν έχετε δημιουργήσει λογαριασμό, πρώτα κάντε %(link)sεγγραφή%(end_link)s" #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Αποσύνδεση" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Είστε σίγουροι ότι θέλετε να αποσυνδεθείτε;" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Δεν μπορείτε να αφαιρέσετε την πρωτεύον διεύθυνση email (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "E-mail επιβεβαίωσης στάλθηκε στο %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Έχετε επιβεβαιώσει το %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Αφαιρέθηκε η διεύθυνση e-mail %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Επιτυχημένη σύνδεση ως %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Έχετε αποσυνδεθεί." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Αλλαγή συνθηματικού ολοκληρώθηκε επιτυχώς." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Συνθηματικό ορίστηκε επιτυχώς." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Ορίστηκε η πρωτεύον διεύθυνση e-mail." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Αλλάξτε Συνθηματικό" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Ξέχασα το συνθηματικό μου" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Ξεχάσατε το συνθηματικό σας? Γράψτε το e-mail σας παρακάτω, και θα σας " "στείλουμε ενα e-mail για να το επαναφέρετε." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Επαναφορά του Συνθηματικού Μου" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Παρακαλούμε επικοινωνήστε μαζί μας αν υπάρξει οποιοδήποτε πρόβλημα κατα την " "επαναφορά του συνθηματικού σας." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Σας στείλαμε ένα e-mail για επαλήθευση.\n" "Παρακαλούμε ακολουθήστε τον σύνδεσμο που αυτό περιέχει. Παρακαλούμε\n" "επικοινωνήστε μαζί μας αν δεν το έχετε παραλάβει μέσα σε λίγα λεπτά." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Μη-έγκυρο Κουπόνι" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Ο σύνδεσμος επαναφορά συνθηματικού δεν ήταν έγκυρος, πιθανών να έχει ήδη " "χρησιμοποιηθεί. Παρακαλούμε κάντε εκ νέου επαναφορά συνθηματικού." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Το συνθηματικό σας έχει αλλάξει." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Ορισμός Συνθηματικού" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Ξέχασα το συνθηματικό μου" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Εγγραφή" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Εγγραφή" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Έχετε ήδη λογαριασμό; Τότε παρακαλούμε %(link)sσυνδεθείτε%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Εγγραφή" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Φραγή Εγγραφών" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Ζητούμε συγνώμη, αλλά η δυνατότητα εγγραφής είναι υπό φραγή." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Σημείωση" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "είστε ήδη συνδεδεμένος ως %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Προσοχη:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Δεν έχετε ρυθμίσει καμία διεύθυνση e-mail. Προτείνουμε να προσθέσετε μία " "ώστε να μπορείτε να λάβετε ειδοποιήσεις, να ανακτήσετε το συνθηματικό σας " "κλπ." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Επιβεβαιώστε την διεύθυνση e-mail σας" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Σας στείλαμε ένα e-mail για επαλήθευση. Ακολουθήστε τον σύνδεσμο που λάβατε " "γιατην ολοκλήρωση της διαδικασίας εγγραφής. Παρακαλούμε επικοινωνήστε μαζί " "μας αν δεν το έχετε παραλάβει μέσα σε λίγα λεπτά." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Αυτή η λειτουργία της σελίδας απαιτεί την επαλήθευση\n" "της ταυτότηας σας. Γι' αυτό, σας ζητούμε να\n" "επαληθεύσετε την ιδιοκτησία της e-mail διεύθυνσης σας. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Σας στείλαμε ένα e-mail για επαλήθευση.\n" "Παρακαλούμε ακολουθήστε τον σύνδεσμο που αυτό περιέχει. Παρακαλούμε\n" "επικοινωνήστε μαζί μας αν δεν το έχετε παραλάβει μέσα σε λίγα λεπτά." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Σημείωση: μπορείτε ακόμα να αλλάξετε τηνδιεύθυνση e-mail σας." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Συνδέσεις Λογαριασμού" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "token secret" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "token secret" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Έχετε επιβεβαιώσει το %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "token secret" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "token secret" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "μυστικό κλειδί" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "μυστικό κλειδί" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Είστε σίγουροι ότι θέλετε να αποσυνδεθείτε;" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "μυστικό κλειδί" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Μη-επιβεβαιωμένο" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "μυστικό κλειδί" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Τρέχον συνθηματικό" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "δημιουργήθηκε" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Σύνδεση μέσω Κοινωνικών Μέσων ανεπιτυχής" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Παρουσιάστηκε ένα σφάλμα κατά την σύνδεση μέσω του λογαριασμού κοινωνικών " "μέσων σας." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Μπορείτε να συνδεθείτε στον λογαριασμό σας με οποιοδήποτε από τους παρακάτω " "εξωτερικούς λογαριασμούς:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Δεν έχετε συνδέσει κανένα λογαριασμό κοινωνικών μέσων με αυτό τον λογαριασμό." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Προσθήκη εξωτερικού λογαριασμού" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Προσθήκη εξωτερικού λογαριασμού" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Προσθήκη εξωτερικού λογαριασμού" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, fuzzy, python-format #| msgid "" #| "You are about to connect a new third party account from %(provider)s." msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Πρόκειται να συνδεθείτε χρησιμοποιώντας έναν λογαριασμό τρίτου μέρους από " "%(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Συνδεθείτε με %(provider)s" #: templates/socialaccount/login.html:20 #, fuzzy, python-format #| msgid "" #| "You are about to connect a new third party account from %(provider)s." msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Πρόκειται να συνδεθείτε χρησιμοποιώντας έναν λογαριασμό τρίτου μέρους από " "%(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Συνέχεια" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Σύνδεση ακυρώθηκε" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Αποφασίσατε να ακυρώσετε την σύνδεση σας στην ιστοσελίδα με έναν από τους " "υπάρχοντες λογαριασμούς σας. Αν έγινε κατά λάθος, παρακαλώ συνδεθείτε." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Ο λογαριασμός κοινωνικών μέσων έχει συνδεθεί." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Ο λογαριασμός κοινωνικών μέσων έχει αποσυνδεθεί." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Πρόκειται να χρησιμοποιήσετε τον %(provider_name)s λογαριασμό σας για να " "συνδεθείτε στην σελίδα\n" "%(site_name)s. Ως τελικό βήμα, παρακαλούμε συμπληρώστε την παρακάτω φόρμα:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Διεύθυνση e-mail" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Τρέχον συνθηματικό" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Συνδέσεις Λογαριασμού" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Το συνθηματικό πρέπει να περιέχει τουλάχιστον {0} χαρακτήρες." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Χαιρετίσματα από το %(site_name)s!\n" #~ "\n" #~ "Λαμβάνετε αυτό το e-mail επειδή εσείς ή κάποιος άλλος έχει κάνει αίτηση " #~ "συνθηματικού για τον λογαριασμό σας.\n" #~ "Αν δεν ζητήσατε επαναφορά συνθηματικού, μπορεί να αγνοηθεί με ασφάλεια. " #~ "Πατήστε στον σύνδεσμο που ακολουθεί για να επαναφέρετε το συνθηματικό σας." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "" #~ "Οι διευθύνσεις e-mail που ακολουθούν είναι συσχετισμένες με τον " #~ "λογαριασμό σας:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Επιβεβαίωση διεύθυνση e-mail" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Παρακαλούμε συνδεθείτε με έναν\n" #~ "από τους ήδη υπάρχοντες εξωτερικούς λογαριασμούς σας. Ή, κάντε εγγραφή\n" #~ "για έναν λογαριασμό %(site_name)s και συνδεθείτε παρακάτω:" #~ msgid "or" #~ msgstr "ή" #~ msgid "change password" #~ msgstr "αλλαγή συνθηματικού" #~ msgid "OpenID Sign In" #~ msgstr "Σύνδεση OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Αυτό το e-mail χρησιμοποιείται ήδη από άλλο λογαριασμό." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Σας έχουμε στείλει ένα e-mail. Παρακαλούμε επικοινωνήστε μαζί μας αν δεν " #~ "το έχετε παραλάβει μέσα σε λίγα λεπτά." django-allauth-65.0.2/allauth/locale/en/000077500000000000000000000000001467545753200200135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/en/LC_MESSAGES/000077500000000000000000000000001467545753200216005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/en/LC_MESSAGES/django.po000066400000000000000000001104761467545753200234130ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2023-07-24 22:28+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "" #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "" #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "" #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "" #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "" #: account/adapter.py:62 msgid "Please type your current password." msgstr "" #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 msgid "Incorrect password." msgstr "" #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "" #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "" #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "" #: account/adapter.py:741 msgid "Use your password" msgstr "" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "" #: account/apps.py:11 msgid "Accounts" msgstr "" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "" #: account/forms.py:93 msgid "Remember Me" msgstr "" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "" #: account/forms.py:123 msgid "Username or email" msgstr "" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "" #: account/forms.py:137 msgid "Forgot your password?" msgstr "" #: account/forms.py:299 msgid "Email (again)" msgstr "" #: account/forms.py:303 msgid "Email address confirmation" msgstr "" #: account/forms.py:311 msgid "Email (optional)" msgstr "" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "" #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "" #: account/forms.py:554 msgid "Current Password" msgstr "" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "" #: account/models.py:34 msgid "verified" msgstr "" #: account/models.py:35 msgid "primary" msgstr "" #: account/models.py:41 msgid "email addresses" msgstr "" #: account/models.py:150 msgid "created" msgstr "" #: account/models.py:151 msgid "sent" msgstr "" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "" #: account/models.py:157 msgid "email confirmation" msgstr "" #: account/models.py:158 msgid "email confirmations" msgstr "" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 msgid "Master key" msgstr "" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "" #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "" #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "" #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "" #: socialaccount/models.py:52 msgid "provider ID" msgstr "" #: socialaccount/models.py:56 msgid "name" msgstr "" #: socialaccount/models.py:58 msgid "client id" msgstr "" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "" #: socialaccount/models.py:63 msgid "secret key" msgstr "" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "" #: socialaccount/models.py:81 msgid "social application" msgstr "" #: socialaccount/models.py:82 msgid "social applications" msgstr "" #: socialaccount/models.py:117 msgid "uid" msgstr "" #: socialaccount/models.py:119 msgid "last login" msgstr "" #: socialaccount/models.py:120 msgid "date joined" msgstr "" #: socialaccount/models.py:121 msgid "extra data" msgstr "" #: socialaccount/models.py:125 msgid "social account" msgstr "" #: socialaccount/models.py:126 msgid "social accounts" msgstr "" #: socialaccount/models.py:160 msgid "token" msgstr "" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "" #: socialaccount/models.py:174 msgid "social application token" msgstr "" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "" #: templates/account/email.html:25 msgid "Verified" msgstr "" #: templates/account/email.html:29 msgid "Unverified" msgstr "" #: templates/account/email.html:34 msgid "Primary" msgstr "" #: templates/account/email.html:44 msgid "Make Primary" msgstr "" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "" #: templates/account/email.html:70 msgid "Add Email" msgstr "" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "" #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "" #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "" #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "" #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "" #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 msgid "Change to" msgstr "" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "" #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "" #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "" #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "" #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "" #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "" #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "" #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "" #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "" #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "" #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "" #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "" #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "" #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "" #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" django-allauth-65.0.2/allauth/locale/es/000077500000000000000000000000001467545753200200205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/es/LC_MESSAGES/000077500000000000000000000000001467545753200216055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/es/LC_MESSAGES/django.po000066400000000000000000001567711467545753200234300ustar00rootroot00000000000000# Traducción al castellano de django-allauth # Copyright (C) 2024 # Quique , 2024. # msgid "" msgstr "" "Project-Id-Version: 0.61.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-23 09:16+0000\n" "Last-Translator: gallegonovato \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Esta cuenta se encuentra ahora mismo desactivada." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "No puede eliminar su correo electrónico principal." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Esta dirección de correo electrónico ya está asociada a esta cuenta." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "" "La dirección de correo electrónico y/o la contraseña que ha indicado no son " "correctas." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Ya hay registrado un usuario con esta dirección de correo electrónico." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Por favor, escriba su contraseña actual." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Código incorrecto." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Contraseña incorrecta." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Clave no válida o caducada." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "El token para restablecer la contraseña no es válido." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "No puede añadir más de %d direcciones de correo electrónico." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Demasiados intentos fallidos. Inténtelo más tarde." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "" "Esta dirección de correo electrónico no está asignada a ninguna cuenta de " "usuario" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Su dirección principal de correo electrónico debe ser verificada." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "No se puede usar este nombre de usuario. Por favor, utilice otro." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "El usuario y/o la contraseña que ha indicado no son correctos." #: account/adapter.py:741 msgid "Use your password" msgstr "Utilice su contraseña" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Utiliza la aplicación o el código de autenticación" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Usar una clave de seguridad" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "" "Marcar las direcciones de correo electrónico seleccionadas como verificadas" #: account/apps.py:11 msgid "Accounts" msgstr "Cuentas" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Debe escribir la misma contraseña cada vez." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Contraseña" #: account/forms.py:93 msgid "Remember Me" msgstr "Recordarme" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Dirección de correo electrónico" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Correo electrónico" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Usuario" #: account/forms.py:123 msgid "Username or email" msgstr "Usuario o correo electrónico" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Iniciar sesión" #: account/forms.py:137 msgid "Forgot your password?" msgstr "¿Ha olvidado tu contraseña?" #: account/forms.py:299 msgid "Email (again)" msgstr "Correo electrónico (otra vez)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Confirmación de la dirección de correo electrónico" #: account/forms.py:311 msgid "Email (optional)" msgstr "Correo electrónico (opcional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Debe escribir el mismo correo electrónico cada vez." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Contraseña (de nuevo)" #: account/forms.py:554 msgid "Current Password" msgstr "Contraseña actual" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nueva contraseña" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nueva contraseña (de nuevo)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Código" #: account/models.py:26 msgid "user" msgstr "usuario" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "dirección de correo electrónico" #: account/models.py:34 msgid "verified" msgstr "verificado" #: account/models.py:35 msgid "primary" msgstr "principal" #: account/models.py:41 msgid "email addresses" msgstr "direcciones de correo electrónico" #: account/models.py:150 msgid "created" msgstr "creado" #: account/models.py:151 msgid "sent" msgstr "enviado" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "clave" #: account/models.py:157 msgid "email confirmation" msgstr "confirmación de correo electrónico" #: account/models.py:158 msgid "email confirmations" msgstr "confirmaciones de correo electrónico" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "No puede añadir una dirección de correo electrónico a una cuenta protegida " "por la autenticación de dos factores." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "No se puede desactivar la autenticación de dos factores." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "No puedes generar códigos de recuperación sin tener activada la " "autenticación de dos factores." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "No puede activar la autenticación de dos factores hasta que haya verificado " "su dirección de correo electrónico." #: mfa/adapter.py:141 msgid "Master key" msgstr "Llave maestra" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Clave de respaldo" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Clave n° {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Códigos de recuperación" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Verificador TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Código de del autenticador" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Passwordless" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Habilitar la operación sin contraseña le permite iniciar sesión usando solo " "esta clave, pero impone requisitos adicionales como biometría o protección " "con PIN." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Ya existe una cuenta con esta dirección de correo electrónico. Por favor, " "primero inicie sesión con esa cuenta, y después vincule su cuenta %s." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Token no válido." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Su cuenta no tiene ninguna contraseña." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Su cuenta no tiene ninguna dirección de correo electrónico verificada." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "No puede desconectar la última cuenta de terceros restante." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Esta cuenta externa ya está asociada a otra cuenta." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Cuentas de redes sociales" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "proveedor" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID del proveedor" #: socialaccount/models.py:56 msgid "name" msgstr "nombre" #: socialaccount/models.py:58 msgid "client id" msgstr "identificador del cliente" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Identificador de App, o clave de consumidor" #: socialaccount/models.py:63 msgid "secret key" msgstr "clave secreta" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" "Clave secreta de la API, clave secreta del cliente o clave secreta del " "consumidor" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Clave" #: socialaccount/models.py:81 msgid "social application" msgstr "aplicación de redes sociales" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplicaciones de redes sociales" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "último inicio de sesión" #: socialaccount/models.py:120 msgid "date joined" msgstr "fecha de incorporación" #: socialaccount/models.py:121 msgid "extra data" msgstr "datos extra" #: socialaccount/models.py:125 msgid "social account" msgstr "cuenta de redes sociales" #: socialaccount/models.py:126 msgid "social accounts" msgstr "cuentas de redes sociales" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) o token de acceso (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "clave secreta del token" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) o token de refresco (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "expira el" #: socialaccount/models.py:174 msgid "social application token" msgstr "token de aplicación de redes sociales" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokens de aplicación de redes sociales" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Datos de perfil no válidos" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Iniciar sesión" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Cancelar" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Respuesta no válida al obtener token de solicitud de \"%s\". La respuesta " "fue: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Respuesta no válida al obtener el token de acceso de \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "No hay token de solicitud guardado para \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "No hay token de acceso guardado para \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Sin acceso a recursos privados de \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Respuesta no válida al obtener token de solicitud de \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Cuenta desactivada" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Esta cuenta está desactivada." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Confirmar acceso" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Por favor, vuelva a autenticarse para proteger su cuenta." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Opciones alternativas" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "Verificación del correo electrónico" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Introduce el código de verificación del correo electrónico" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Hemos enviado un código a %(email_link)s. El código caduca en breve, así que " "introdúcelo pronto." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Confirmar" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Iniciar sesión" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Ingrese el código de inicio de sesión" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Direcciones de correo electrónico" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "" "Las siguientes direcciones de correo electrónico están asociadas a su cuenta:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verificado" #: templates/account/email.html:29 msgid "Unverified" msgstr "Sin verificar" #: templates/account/email.html:34 msgid "Primary" msgstr "Principal" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Definir como principal" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Reenviar Verificación" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Eliminar" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Añadir correo electrónico" #: templates/account/email.html:70 msgid "Add Email" msgstr "Añadir correo electrónico" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "" "¿Seguro que desea eliminar la dirección de correo electrónico seleccionada?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Usted está recibiendo este correo electrónico porque usted u otra persona " "intentó registrarse para una\n" "cuenta utilizando la siguiente dirección de correo electrónico:\n" "\n" "%(email)s\n" "\n" "Sin embargo, ya existe una cuenta con esa dirección de correo electrónico. " "En caso de que lo haya\n" "olvidado, utilice el procedimiento de recuperació de contraseña olvidada " "para recuperar\n" "su cuenta:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "La cuenta ya existe" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "¡Hola de parte de %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "¡Gracias por usar %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Está recibiendo este correo porque se ha realizado el siguiente cambio en su " "cuenta:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Si no reconoce este cambio, tome inmediatamente las precauciones de " "seguridad adecuadas. El cambio en su cuenta se origina en:\n" "\n" "- Dirección IP: %(ip)s\n" "- Navegador: %(user_agent)s\n" "- Fecha: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Tu email ha sido cambiado de %(from_email)s a %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Correo electrónico modificado" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Su correo electrónico ha sido verificado." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Correo electrónico confirmado" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Estás recibiendo este correo electrónico porque el usuario %(user_display)s " "ha facilitado tu dirección de correo electrónico para registrar una cuenta " "en %(site_domain)s." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Tu código de verificación de correo electrónico aparece a continuación. Por " "favor, introdúcelo en la ventana abierta de tu navegador." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Para confirmar que esto es correcto, vete a %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Por favor, confirme su dirección de correo electrónico" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" "La dirección de correo electrónico %(deleted_email)s ha sido eliminada de tu " "cuenta." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Correo electrónico eliminado" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Su código de inicio de sesión se enumera a continuación. Introdúzcalo en la " "ventana abierta de su navegador." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Este correo puede ser ignorado con seguridad si usted no inició esta acción." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Código de inicio de sesión" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Su contraseña ha sido modificada." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Contraseña modificada" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Está recibiendo este correo electrónico porque usted u otra persona ha " "solicitado un restablecimiento de contraseña para su cuenta de usuario.\n" "Puede ignorar este correo si no ha solicitado este cambio. Haga clic en el " "siguiente enlace para restablecer su contraseña." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "En caso de haberlo olvidado, su usuario es %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Correo electrónico para restablecer contraseña" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Su contraseña ha sido restablecida." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Restablecer Contraseña" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Su contraseña ha sido establecida." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Establecer contraseña" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Está recibiendo este correo electrónico porque usted, u otra persona, " "intentó acceder a una cuenta con email %(email)s. Sin embargo, no tenemos " "constancia de dicha cuenta en nuestra base de datos." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Si ha sido usted, puede registrarse para obtener una cuenta utilizando el " "siguiente enlace." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Cuenta desconocida" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Correo electrónico" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Correo electrónico actual" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Cambiando a" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Su dirección de correo electrónico sigue pendiente de verificación." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Cancelar el cambio" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Cambiar a" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Cambiar correo electrónico" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Confirmar dirección de correo electrónico" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Por favor, confirme que %(email)s es una " "dirección de correo electrónico para el usuario %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "No se puede confirmar %(email)s porque ya está confirmado por otra cuenta." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Este enlace de confirmación por correo electrónico ha caducado o no es " "válido. Por favor, emita una nueva solicitud de " "confirmación por correo electrónico." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Si aún no ha creado una cuenta, por favor %(link)sregístrese%(end_link)s " "primero." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Iniciar sesión con un passkey" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Envíame un código de inicio de sesión" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Cerrar sesión" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "¿Seguro que desea cerrar sesión?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "No puede eliminar su correo electrónico principal (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Correo electrónico de confirmación enviado a %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Ha confirmado %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Correo electrónico %(email)s eliminado." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Ha iniciado sesión exitosamente como %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Ha cerrado sesión." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Se ha enviado un código de inicio de sesión por correo a %(email)s ." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Contraseña cambiada con éxito." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Contraseña establecida con éxito." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Dirección principal de correo electrónico establecida." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Cambiar la contraseña" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "¿Olvidó su contraseña?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "¿Ha olvidado su contraseña? Introduzca su dirección de correo electrónico, y " "le enviaremos un correo que le permitirá restablecerla." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Restablecer mi contraseña" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Si tiene alguna dificultad para restablecer su contraseña, por favor " "contáctenos." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Le hemos enviado un correo electrónico. Si no lo ha recibido, compruebe su " "carpeta de correo no deseado. De lo contrario, póngase en contacto con " "nosotros si no lo recibe en unos minutos." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Hay un problema con el token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "El enlace para restablecer la contraseña es inválido, probablemente porque " "ya ha sido utilizado. Por favor solicite restablecer la contraseña de nuevo." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Su contraseña ha cambiado." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Establecer contraseña" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Introduzca su contraseña:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Recibirá un correo electrónico que contiene un código especial para iniciar " "sesión sin contraseña." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Solicite el código" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Otras opciones de inicio de sesión" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registro" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registrarse" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "¿Ya tiene una cuenta? Por favor %(link)sinicie sesión%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Regístrate usando una passkey" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Regítrate con passkey" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Otras opciones" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registro cerrado" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Lo sentimos, en este momento el registro está cerrado." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Nota" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Ya ha iniciado sesión como %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Advertencia:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Actualmente no tienes ninguna dirección de correo electrónico configurada. " "Debería añadir una dirección de correo electrónico para recibir " "notificaciones, restablecer su contraseña, etc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifique su dirección de correo electrónico" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Le hemos enviado un correo electrónico para su verificación. Siga el enlace " "proporcionado para finalizar el proceso de registro. Si no ves el correo " "electrónico de verificación en tu bandeja de entrada principal, comprueba tu " "carpeta de correo no deseado. Por favor, póngase en contacto con nosotros si " "no recibe el correo electrónico de verificación en unos minutos." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Esta parte de la página requiere que verifiquemos que\n" "usted es quien dice ser. Para ello, le pedimos que\n" "verifique la titularidad de su dirección de correo electrónico. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Le hemos enviado un correo electrónico para\n" "verificación. Por favor, haga clic en el enlace que aparece en ese correo " "electrónico. Si no ve el correo electrónico de verificación en su bandeja de " "entrada principal, compruebe su carpeta de correo no deseado. De lo " "contrario,\n" "póngase en contacto con nosotros si no lo recibe en unos minutos." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Nota: aún puedes cambiar tu " "dirección de correo electrónico." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Mensajes:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menú:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Conexiones de Cuenta" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Autenticació de doble factor" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sesiones" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Su cuenta está protegida por doble factor de autenticación. Por favor, entre " "el código del autenticador:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "Se ha generado un nuevo conjunto de códigos de recuperación de Autenticación " "de Dos Factores." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Generados nevos códigos de recuperación" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "La aplicación de autenticación ha sido activada." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Aplicación de autenticación activada" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Aplicación de autenticación desactivada." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Aplicación de autenticación desactivada" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Se ha agregado una nueva clave de seguridad." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Clave de seguridad añadida" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Se ha eliminado una clave de seguridad." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Clave de seguridad eliminada" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Aplicación de autenticación" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "La autenticación con una aplicación de autenticación está activa." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "No hay ninguna aplicación de autenticación activa." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Desactivar" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Activar" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Claves de seguridad" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Has añadido %(count)s clave." msgstr[1] "Has añadido %(count)s claves." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "No se han agregado claves de seguridad." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Administrar" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Añadir" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Códigos de recuperación" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Hay %(unused_count)s de %(total_count)s código de recuperación disponibles." msgstr[1] "" "Hay %(unused_count)s de %(total_count)s códigos de recuperación disponibles." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "No se han configurado códigos de recuperación." #: templates/mfa/index.html:96 msgid "View" msgstr "Mostrar" #: templates/mfa/index.html:102 msgid "Download" msgstr "Descargar" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Generar" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Se ha generado un nuevo conjunto de código de recuperación." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Clave de seguridad añadida." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Clave de seguridad eliminada." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Ingrese un código de autenticación:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Está a punto de generar un nuevo conjunto de código de recuperación para su " "cuenta." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Esta operación invalidará sus códigos existentes." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "¿Está seguro?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Códigos no utilizados" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Descarga los códigos" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Crear nuevos códigos" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Activar la aplicación de autenticación" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Escanee el código QR a continuación con su aplicación de autenticación para " "proteger su cuenta con autenticación de dos factores. Luego, ingrese el " "código de verificación generado por la aplicación a continuación." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Secreto de autenticador" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Puede guardar este secreto y usarlo más tarde para reinstalar su aplicación " "de autenticación." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Deshabilitar la aplicación de autenticación" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Está a punto de desactivar la autenticación a través de la aplicación de " "autenticación. ¿Está seguro?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Añadir una clave de seguridad" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Eliminar clave de seguridad" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "¿Estás seguro de que deseas eliminar esta clave de seguridad?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Uso" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Passkey" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Clave de seguridad" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Esta clave no indica si es una clave de acceso." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Sin especificar" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Añadida el %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Usada por última vez %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Editar" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Editar la clave de seguridad" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Guardar" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "Crear una passkey" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" "Estás a punto de crear una passkey para tu cuenta. Como puedes añadir claves " "adicionales más adelante, puedes utilizar un nombre descriptivo para " "diferenciar las claves." #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "Crear" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Esta funcionalidad requiere JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Falló la autenticación de terceros" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Se produjo un error al intentar iniciar sesión a través de su cuenta de " "terceros." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Puede iniciar sesión en su cuenta utilizando una de las siguientes cuentas " "de terceros:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Actualmente no tiene cuentas de terceros conectadas a esta cuenta." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Agregar una cuenta de terceros" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "Una cuenta de terceros de %(provider)s se ha conectado a su cuenta." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Cuenta de terceros vinculada" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "La cuenta de terceros desde %(provider)s ha sido desvinculada de tu cuenta." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Cuenta de terceros desconectada" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Conectar %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Se dispone a conectarse a una nueva cuenta externa de %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Inicio de sesión mediante %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Se dispone a iniciar sesión usando una cuenta externa desde %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Continuar" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Inicio de sesión cancelado" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Ha decidido cancelar el inicio de sesión en nuestro sitio usando una de sus " "cuentas. Si ha sido un error, por favor inicie " "sesión." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "La cuenta externa ha sido conectada." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "La cuenta externa ha sido desconectada." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Se dispone a usar su cuenta de %(provider_name)s para acceder a " "%(site_name)s.\n" "Como paso final, por favor complete el siguiente formulario:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "O use una cuenta de terceros" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Se han cerrado todas las demás sesiones." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Iniciada el" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "Dirección IP" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Navegador" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Visto por última vez" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Actual" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Cerrar las demás sesiones" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Sesiones de usuario" #: usersessions/models.py:92 msgid "session key" msgstr "clave de sesión" #~ msgid "Account Connection" #~ msgstr "Conexiones de la cuenta" #~ msgid "Use security key or device" #~ msgstr "Usar clave o dispositivo de seguridad" #~ msgid "Add Security Key or Device" #~ msgstr "Agregar clave de seguridad o dispositivo" #~ msgid "Add key or device" #~ msgstr "Agregar clave o dispositivo" #~ msgid "Security Keys and Devices" #~ msgstr "Dispositivos y claves de seguridad" #~ msgid "You have not added any security keys/devices." #~ msgstr "No ha agregado ninguna clave/dispositivo de seguridad." #~ msgid "Edit Security Key or Device" #~ msgstr "Editar clave o dispositivo de seguridad" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "La contraseña necesita al menos {0} caracteres." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Está recibiendo este correo electrónico porque usted u otra persona ha " #~ "solicitado una\n" #~ "contraseña para su cuenta de usuario. Sin embargo, no tenemos ningún " #~ "registro de un usuario\n" #~ "con email %(email)s en nuestra base de datos.\n" #~ "\n" #~ "Este correo puede ser ignorado con seguridad si usted no solicitó un " #~ "restablecimiento de contraseña.\n" #~ "\n" #~ "Si has sido tú, puedes registrarte para obtener una cuenta utilizando el " #~ "siguiente enlace." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "" #~ "Las siguientes direcciones de correo electrónico están asociadas a su " #~ "cuenta:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Confirmar dirección de correo electrónico" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Por favor, inicie sesión con una\n" #~ "cuenta de otra red social. O %(link)sregístrese%(end_link)s \n" #~ "como usuario de %(site_name)s e inicie sesión a continuación:" #~ msgid "or" #~ msgstr "o" #~ msgid "change password" #~ msgstr "cambiar la contraseña" #~ msgid "OpenID Sign In" #~ msgstr "Iniciar sesión con OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Este correo electrónico ya está asociado con otra cuenta." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Le hemos enviado un correo electrónico. Por favor contáctenos si no lo " #~ "recibe en unos minutos." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "" #~ "El correo electrónico/usuario y/o la contraseña que especificó no son " #~ "correctos." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Los nombres de usuarios pueden contener solamente letras, números, y @/./" #~ "+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Este usuario ya está en uso. Por favor elije otro." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Iniciar sesión" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Has confirmado que %(email)s es una " #~ "dirección de correo electrónico del usuario %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "¡Gracias por utilizar nuestro sitio!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Correo de confirmación enviado a %(email)s" #~ msgid "Delete Password" #~ msgstr "Eliminar Contraseña" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "Puedes eliminar tu contraseña ya que ingresaste con OpenID." #~ msgid "delete my password" #~ msgstr "eliminar mi contraseña" #~ msgid "Password Deleted" #~ msgstr "Contraseña Eliminada" django-allauth-65.0.2/allauth/locale/et/000077500000000000000000000000001467545753200200215ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/et/LC_MESSAGES/000077500000000000000000000000001467545753200216065ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/et/LC_MESSAGES/django.po000066400000000000000000001414571467545753200234240ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:55+0200\n" "Last-Translator: Gregor Grigorjan \n" "Language-Team: LANGUAGE \n" "Language: Estonian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "See konto on parajasti mitteaktiivne." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Primaarset e-posti aadressi (%(email)s) ei saa eemaldada." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "See e-posti aadress on juba selle kontoga seostatud." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Sisestatud e-posti aadress või salasõna ei ole õige." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Selle e-posti aadressiga on juba kasutaja registreeritud." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Palun sisesta oma praegune salasõna." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Vale kood." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Vale salasõna." #: account/adapter.py:65 #, fuzzy #| msgid "Invalid token." msgid "Invalid or expired key." msgstr "Vale tooken." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Salasõna taasseadmise tooken oli vale." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Sa ei tohi lisada enam kui %d e-posti aadressi." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Liiga palju nurjunud sisse logimise katseid. Proovi hiljem uuesti." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "See e-posti aadress pole määratud ühelegi kontole." #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Su primaarne e-posti aadress peab olema kinnitatud." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Kasutajanime pole lubatud kasutada. Palun kasuta muud kasutajanime." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Sisestatud kasutajanimi või salasõna ei ole õige." #: account/adapter.py:741 msgid "Use your password" msgstr "Kasuta oma salasõna" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "Kasuta oma autentimisrakendust" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "salavõti" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Märgi valitud e-posti aadressid kinnitatuks" #: account/apps.py:11 msgid "Accounts" msgstr "Kontod" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Pead sisestama sama salasõna iga kord." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Salasõna" #: account/forms.py:93 msgid "Remember Me" msgstr "Jäta mind meelde" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-posti aadress" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-post" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Kasutajanimi" #: account/forms.py:123 msgid "Username or email" msgstr "Kasutajanimi või e-post" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Logi sisse" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Unustasid salasõna?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-post (uuesti)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "E-posti aadress" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-post (valikuline)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Pead sisetama sama e-posti aadressi iga kord." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Salasõna (uuesti)" #: account/forms.py:554 msgid "Current Password" msgstr "Praegune salasõna" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Uus salasõna" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Uus salasõna (uuesti)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kood" #: account/models.py:26 msgid "user" msgstr "kasutaja" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-posti aadress" #: account/models.py:34 msgid "verified" msgstr "kinnitatud" #: account/models.py:35 msgid "primary" msgstr "primaarne" #: account/models.py:41 msgid "email addresses" msgstr "e-posti aadressid" #: account/models.py:150 msgid "created" msgstr "loodud" #: account/models.py:151 msgid "sent" msgstr "saadetud" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "võti" #: account/models.py:157 msgid "email confirmation" msgstr "kinnitus e-posti kaudu" #: account/models.py:158 msgid "email confirmations" msgstr "kinnitused e-posti kaudu" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Sa ei saa kaheastmelise autentimisega turvatud kontole lisada e-posti " "aadressi." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Sa ei saa kaheastmelist autentimist välja lülitada." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "Sa ei saa luua varukoode ilma kaheastmilise autentimiseta." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Sa ei saa välja lülitada kaheastmelist autentimist kuni sa oled oma e-posti " "aadressi kinnitanud." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "salavõti" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "Mitmeastmeline autentimine" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Varukoodid" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Paroolikell" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Autentimiskood" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Salasõna" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Selle e-posti aadressiga konto on juba olemas. Palun logi esmalt sellesse " "kontosse sisse, siis ühenda oma %s konto." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Vale tooken." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Su kontol pole salasõna määratud." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Su kontol pole kinnitatud e-posti aadresse." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third-party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Saad sisse logida oma kontosse kasutades mistahes järgnevatest kolmanda " "osapoole kontodest:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "See kolmanda osapoole konto on juba mõne teise kontoga ühendatud." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sotsiaalkontod" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "tarnija" #: socialaccount/models.py:52 msgid "provider ID" msgstr "tarnija ID" #: socialaccount/models.py:56 msgid "name" msgstr "nimi" #: socialaccount/models.py:58 msgid "client id" msgstr "kliendi id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Rakenduse ID, või tarnija id" #: socialaccount/models.py:63 msgid "secret key" msgstr "salavõti" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API salajane võti, kliendi salajane võti, või tarnija salajane võti" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Võti" #: socialaccount/models.py:81 msgid "social application" msgstr "sotsiaalrakendus" #: socialaccount/models.py:82 msgid "social applications" msgstr "sotsiaalrakendused" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "viimane sisse logimine" #: socialaccount/models.py:120 msgid "date joined" msgstr "liitumise kuupäev" #: socialaccount/models.py:121 msgid "extra data" msgstr "lisaandmed" #: socialaccount/models.py:125 msgid "social account" msgstr "sotsiaalkonto" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sotsiaalkontod" #: socialaccount/models.py:160 msgid "token" msgstr "tooken" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "aegub" #: socialaccount/models.py:174 msgid "social application token" msgstr "sotsiaalrakenduse tooken" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "sotsiaalrakenduse tookenid" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Valed profiiliandmed" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Logi sisse" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Tühista" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Väär vastus päringutookenit tarnijalt \"%s\" hankides. Vastus oli: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Väär vastus pääsutookenit tarnijalt \"%s\" hankides." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Päringutookenit pole salvestatud \"%s\" jaoks." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Pääsutookenit pole salvestatud \"%s\" jaoks." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Puudub ligipääs \"%s\" privaatressurssidele." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Väär vastus tarnijalt \"%s\" pääsutookenit hankides." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Konto mitteaktiivne" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "See konto on mitteaktiivne." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Kinnita ligipääs" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Palun tuvasta end uuesti, et turvata oma kontot." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Muud valikud" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "E-posti kinnitus" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Sisesta autentimisrakenduse kood:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Saatsime koodi %(email_link)s. Kood aegub varsti, seega sisestaga see " "kiiresti." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Kinnita" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Logi sisse" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Sisesta sisselogimiskood" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-posti aadressid" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Sinu kontoga on seostatud järgnevad e-posti aadressid:" #: templates/account/email.html:25 msgid "Verified" msgstr "Kinnitatud" #: templates/account/email.html:29 msgid "Unverified" msgstr "Kinnitamata" #: templates/account/email.html:34 msgid "Primary" msgstr "Primaarne" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Muuda primaarseks" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Saada kinnitus uuesti" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Eemalda" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Lisa e-posti aadress" #: templates/account/email.html:70 msgid "Add Email" msgstr "Lisa e-post" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Oled kindel, et soovid valitud e-posti aadressi eemaldada?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Te saite selle kirja kuna kas Teie või keegi teine proovis luua konto\n" "kasutades teie e-posti aadressi:\n" "\n" "%(email)s\n" "\n" "Selle e-posti aadressiga konto on juba olemas. Juhul, kui Te olite selle\n" "unustanud, siis palun kasutage ununenud salasõna protseduuri, et saada ligi\n" "oma kontole:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Konto on juba olemas" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "%(site_name)s tervitab!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Täname, et kasutate teenust %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Te saite selle kirja, kuna Teie kontoga tehti järgnev muudatus:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Kui Te ei tunnista seda muudatust, siis turvake oma kontot kohe. Muudatus " "kontole tuli järgnevast allikast:\n" "\n" "- IP aadress: %(ip)s\n" "- Veebilehitseja: %(user_agent)s\n" "- Kuupäev: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" "Teie e-posti aadress muudeti. Vana e-posti aadress: %(from_email)s. Uus e-" "posti aadress: %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E-post muudetud" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Teie e-posti aadress on kinnitatud." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "E-posti kinnitus" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Te saite selle kirja kuna kasutaja %(user_display)s sisestas teie e-posti " "aadressi, et registreerida konto lehel %(site_domain)s.\n" "\n" "Kinnitamaks taotluse õigsust, minge %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Teie sisselogimiskood on alljärgnevalt esitatud. Palun sisestage see oma " "veebilehitseja avatud aknas." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Palun kinnitage oma e-posti aadress" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "E-posti aadress %(deleted_email)s on Teie kontolt eemaldatud." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "E-post eemaldatud" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Teie sisselogimiskood on alljärgnevalt esitatud. Palun sisestage see oma " "veebilehitseja avatud aknas." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Seda kirja võib eirata, kui Te ise seda toimingut ei algatanud." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Sisselogimiskood" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Teie salasõna muudeti." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Salasõna muudetud" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Te saite selle kirja kuna Teie või keegi teine algatas Teie kontol parooli " "taasseadmise.\n" "Te võite seda kirja ignoreerida, kui Teie seda ei algatanud. Klõpsake " "alljärgneval lingil, et taasseada oma salasõna." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Juhuks, kui unstasite, Teie kasutajanimi on %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Salasõna taasseadmine" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Teie salasõna on taasseatud." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Salasõna taasseadmine" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Teie salasõna on seatud." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Salasõna seatud" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Te saite selle kirja kuna Teie, või keegi teine, proovis pääseda ligi Teie " "kontole e-posti aadressiga %(email)s. Ent meil pole ühtegi kirjet sellise e-" "posti aadressiga kontost andmebaasis." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Kui see olite Teie, siis saate registreerida konto kasutades alljärgnevat " "linki." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Tundmatu konto" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "E-posti aadress" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Praegune e-post" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Muudatus" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Su e-posti aadress on endiselt kinnitamata." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Tühista muudatus" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Uus e-post" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Muuda e-posti" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Kinnita e-posti aadress" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Palun kinnita, et %(email)s on konto " "%(user_display)s e-posti aadress." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Ei saa kinnitada aadressi %(email)s kuna see on juba teise kontoga " "kinnitatud." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "See e-posti aadressi kinnituslink aegus või on vale. Palun taotlege uus e-posti aadressi kinnitamine." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Kui sa pole veel kontot loonud, siis palun esmalt " "%(link)sregistreeruge%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Saada mulle sisselogimiskood" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Logi välja" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Oled kindel, et soovid välja logida?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Primaarset e-posti aadressi (%(email)s) ei saa eemaldada." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Kinnituskiri saadeti aadressile %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Sa kinnitasid e-posti aadressi %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "E-posti aadress %(email)s eemaldatud." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Logisid edukalt sisse kasutajana %(name)s" #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Sa logisid välja." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Sisselogimisekood saadeti aadressile %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Salasõna muudeti edukalt." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Salasõna seati edukalt." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primaarne e-posti aadress on nüüd seatud." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Muuda salasõna" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Unustasid salasõna?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Unustasid oma salasõna? Sisesta allpool oma e-posti aadress, ning me saadame " "sulle kirja, mille abil saad selle taasseada." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Taassea minu salasõna" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Palun võta meiega ühendust, kui näed vaeva oma salasõna taasseadmisega." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Saatsime teile e-kirja. Kui sa pole seda kätte saanud, siis vaata rämpsposti " "kausta. Muul juhul, võta meiega ühendust kui sa ei saa seda mõne minuti " "jooksul kätte." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Vale tooken" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Salasõna taasseadmise link oli vale. On võimalik, et seda oli juba " "kasutatud. Palun taotle uus salasõna " "taasseadmine." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Su salasõna on nüüd muudetud." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Sea salasõna" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Sisesta oma salasõna:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "Sa saad e-kirja, mis sisaldab koodi paroolivabaks sisselogimiseks." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Taotle koodi" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Muud sisse logimise võimalused" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registreerimine" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registreeri" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Konto juba olemas? Palun %(link)slogi sisse%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Registreeri" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Muud sisse logimise võimalused" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Sisselogimine peatatud" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Sisselogimine on parajasti peatatud. Palume vabandust!" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Teavitus" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Sa oled juba sisse logitud kasutajana %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Hoiatus:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Su kontol pole parajasti ühtegi e-posti aadressi. Soovitame kindlasti seada " "e-posti aadressi, et sa saaksid saada teavitusi, taasseada salasõna jne." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Kinnita oma e-posti aadress" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Saatsime sulle kinnituseks e-kirja. Järgi kirjas olevat linki, et lõpetada " "registreerimine. Kui sa ei näe kinnituskirja postkastis, kontrolli " "rämpsposti kausta. Palun võta meiega ühendust, kui sa ei saa kinnituskirja " "mõne minuti jooksul." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "See osa lehest nõuab, et me kinnitaksime sinu sisestatud andmeid. Selle " "tarbeks nõuame kinnitust, et\n" "oled oma e-posti aadressi omanik. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Saatsime teile kinnituseks e-kirja. Palun klõpsa kirja sees olevale lingile. " "Kui sa ei näe kinnituskirja oma postkastis, siis vaata rämpsposti kausta. " "Vastasel juhul,\n" "võta meiega ühendust kui sa ei saa kirja mõne minuti jooksul." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Märkus: saad ikka oma e-posti " "aadressi muuta." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Sõnumid" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menüü:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Konto sidemed" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Kaheastmeline autentimine" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sessioonid" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Su konto on turvatud kaheastmelise autentimisega. Palun sisesta " "autentimiskood:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Uus hulk kaheastmelise autentimise varukoode on loodud." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Uued varukoodid loodud" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Autentimisrakendus seadistatud" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Autentimisrakendus seadistatud" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Autentimisrakendus eemaldatud" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Autentimisrakendus eemaldatud" #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "Uus hulk varukoode on loodud." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your email has been confirmed." msgid "A security key has been removed." msgstr "Teie e-posti aadress on kinnitatud." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Autentimisrakendus" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Autentimine kasutades autentimisrakendust on seadistatud." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Ühtegi autentimisrakendust pole seadistatud." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Eemalda" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Seadista" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Varukoodid" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Võimalikke varukoode on %(total_count)s, ning nendest %(unused_count)s on " "saadaval." msgstr[1] "" "Võimalikke varukoode on %(total_count)s, ning nendest %(unused_count)s on " "saadaval." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Varukoode pole seadistatud" #: templates/mfa/index.html:96 msgid "View" msgstr "Vaata" #: templates/mfa/index.html:102 msgid "Download" msgstr "Lae alla" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Loo" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Uus hulk varukoode on loodud." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Sisesta autentimisrakenduse kood:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Järgnevalt loote uue hulga varukoode oma kontole." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "See tegevus muudab olemasolevad varukoodid kehtetuks." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Oled kindel?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Kasutamata varukoodid" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Lae varukoodid alla" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Loo uued varukoodid" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Seadista autentimisrakendus" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Et turvata oma kontot kaheastmelise autentimisega, skänni alljärgnev QR-kood " "oma autentimisrakendusega. Seejärel, sisesta rakenduse loodud kinnituskood " "all olevasse lahtrisse." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Autentimisrakenduse saladus" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Hoiustades selle saladuse saad seda kasutada, et taaspaigaldada oma " "autentimisrakendust tulevikus." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Eemalda autentimisrakendus" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Järgneva tegevusega eemaldad autentimisrakendusega seotud autentimise. Kas " "oled kindel?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "salavõti" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "salavõti" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Oled kindel, et soovid välja logida?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "salavõti" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Kinnitamata" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "salavõti" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Praegune salasõna" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "loodud" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Kolmanda osapoolega sisse logimine nurjus" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Kolmanda osapoole konto kaudu sisse logimise ajal tekkis viga." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Saad sisse logida oma kontosse kasutades mistahes järgnevatest kolmanda " "osapoole kontodest:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Su kontoga pole parajasti seotud ühtegi kolmanda osapoole kontot." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Lisa kolmanda osapoole konto" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "Kolmanda osapoole %(provider)s konto on Teie kontoga ühendatud." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Kolmanda osapoole konto ühendatud" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "Seos kolmanda osapoole %(provider)s konto ja Teie konto vahel on eemaldatud." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Kolmanda osapoole konto eemaldatud" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Ühenda %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Järgneva tegevusega ühendate uue kolmanda osapoole konto pakkujalt " "%(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Logi sisse %(provider)s kaudu" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Järgneva tegevusega logite sisse kasutades kolmanda osapoole %(provider)s " "kontot." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Jätka" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Sisse logimine tühistatud" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Otsustasid meie lehte sisse logimise tühistada.Kui see oli eksimus, palun " "mine sisse logima." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Kolmanda osapoole konto on ühendatud." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Seos kolmanda osapoole kontoga eemaldati." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Järgneva tegevusega kasutate pakkuja %(provider_name)s kontot sisse " "logimiseks lehele\n" "%(site_name)s. Viimase sammuna, palun täitke ankeet:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Või kasuta kolmandat osapoolt" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Kõigist teistest sessioonidest välja logitud." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Alustati" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP aadress" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Veebilehitseja" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Viimati nähtud" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Praegune" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Logi teistest sessioonidest välja" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Kasutajasessioonid" #: usersessions/models.py:92 msgid "session key" msgstr "sessioonivõti" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Konto sidemed" django-allauth-65.0.2/allauth/locale/eu/000077500000000000000000000000001467545753200200225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/eu/LC_MESSAGES/000077500000000000000000000000001467545753200216075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/eu/LC_MESSAGES/django.po000066400000000000000000001466131467545753200234240ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:11+0200\n" "Last-Translator: Eneko Illarramendi \n" "Language-Team: Basque \n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.1.1\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Kontu hau ez dago aktiboa orain." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Ezin duzu zure helbide elektroniko nagusia ezabatu (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Helbide elektroniko hau dagoeneko kontu honi lotuta dago." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Sartutako helbide elektronikoa eta/edo pasahitza ez dira zuzenak." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "" "Erabiltzaile batek kontu bat sortu du iada helbide elektroniko honekin." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Mesedez idatzi zure oraingo pasahitza." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Oraingo pasahitza" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Token baliogabea" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Pasahitza berrezartzeko \"token\"-a baliogabea da." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Ezin dituzu %d email helbide baino gehiago erabili." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Huts egite gehiegi saioa hasterakoan. Saiatu berriro beranduago." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Helbide elektroniko hau ez dago kontu bati lotuta" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Zure email nagusiak egiaztatuta egon behar du." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Erabiltzaile izen hau ezin da erabili. Aukeratu beste erabiltzaile izen bat." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Sartutako erabiltzailea eta/edo pasahitza ez dira zuzenak." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Pasahitza ahaztu duzu?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "\"token secret\"-a" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "\"secret key\"-a" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Zure email nagusiak egiaztatuta egon behar du." #: account/apps.py:11 msgid "Accounts" msgstr "Kontuak" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Pasahitz berdina idatzi behar duzu aldi bakoitzean." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Pasahitza" #: account/forms.py:93 msgid "Remember Me" msgstr "Gogora nazazue" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Helbide elektronikoa" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Emaila" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Erabiltzailea" #: account/forms.py:123 msgid "Username or email" msgstr "Erabiltzailea edo emaila" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Logina" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Pasahitza ahaztu duzu?" #: account/forms.py:299 msgid "Email (again)" msgstr "Emaila (berriro)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Helbide elektronikoaren egiaztapena" #: account/forms.py:311 msgid "Email (optional)" msgstr "Emaila (hautazkoa)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Email berdina idatzi behar duzu aldi bakoitzean." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Pasahitza (berriro)" #: account/forms.py:554 msgid "Current Password" msgstr "Oraingo pasahitza" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Pasahitz berria" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Pasahitz berria (berriro)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "erabiltzailea" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "helbide elektronikoa" #: account/models.py:34 msgid "verified" msgstr "egiaztatuta" #: account/models.py:35 msgid "primary" msgstr "nagusia" #: account/models.py:41 msgid "email addresses" msgstr "helbide elektronikoak" #: account/models.py:150 msgid "created" msgstr "sortuta" #: account/models.py:151 msgid "sent" msgstr "bidalita" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "giltza" #: account/models.py:157 msgid "email confirmation" msgstr "email egiaztapena" #: account/models.py:158 msgid "email confirmations" msgstr "email egiaztapenak" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "\"secret key\"-a" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Pasahitza" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Kontu bat sortu da iada helbide elektroniko honekin. Mesedez hasi saio berri " "bat kontu honekin eta gero zure %s kontua honi lotu." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Token baliogabea" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Zure kontuak ez du pasahitzik zehaztuta." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Zure kontuak ez du egiaztatutako emailik." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Ondorengo zerbitzu hauetako edozein erabili dezakezu zure kontuan sartzeko:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Sare sozial kontua dagoeneko beste kontu bati lotuta dago." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sare sozial kontuak" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "zerbitzua" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "zerbitzua" #: socialaccount/models.py:56 msgid "name" msgstr "izena" #: socialaccount/models.py:58 msgid "client id" msgstr "client id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Aplikazioaren ID-a, edo \"consumer key\"-a" #: socialaccount/models.py:63 msgid "secret key" msgstr "\"secret key\"-a" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "\"API secret\"-a, \"client secret\"-a edo \"consumer secret\"-a" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Giltza" #: socialaccount/models.py:81 msgid "social application" msgstr "aplikazio soziala" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplikazio sozialak" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "azken logina" #: socialaccount/models.py:120 msgid "date joined" msgstr "erregistro eguna" #: socialaccount/models.py:121 msgid "extra data" msgstr "datu gehigarriak" #: socialaccount/models.py:125 msgid "social account" msgstr "sare sozial kontua" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sare sozial kontuak" #: socialaccount/models.py:160 msgid "token" msgstr "\"token\"-a" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\"-a (OAuth1) edo \"access token\"-a (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "\"token secret\"-a" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\"-a (OAuth1) edo \"refresh token\"-a (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "iraungitze data" #: socialaccount/models.py:174 msgid "social application token" msgstr "aplikazio sozial \"token\"-a" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "aplikazio sozial \"token\"-ak" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Profil datu baliogabeak" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Logina" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Erantzun baliogabea \"%s\"-tik \"request token\"-a eskuratzean." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Erantzun baliogabea \"%s\"-tik \"access token\"-a eskuratzean." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Ez dago \"request token\"-ik gordeta \"%s\"-entzat." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Ez dago \"access token\"-ik gordeta \"%s\"-entzat." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Ez duzu baliabide pribatuetara sarbiderik: \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Erantzun baliogabea \"%s\"-tik \"request token\"-a eskuratzean." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Kontu ez aktiboa" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Kontu hau ez dago aktiboa." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Helbide elektronikoa egiaztatu" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "email egiaztapena" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "\"token secret\"-a" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Egiaztatu" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Saioa hasi" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Helbide elektronikoak" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Helbide elektroniko hauek zure kontuari lotuta daude:" #: templates/account/email.html:25 msgid "Verified" msgstr "Egiaztatuta" #: templates/account/email.html:29 msgid "Unverified" msgstr "Egiaztatu gabe" #: templates/account/email.html:34 msgid "Primary" msgstr "Nagusia" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Nagusia egin" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Egiaztapen emaila berbidali" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Ezabatu" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Helbide elektronikoa gehitu" #: templates/account/email.html:70 msgid "Add Email" msgstr "Emaila gehitu" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Ziur al zaude aukeratutako helbide elektronikoa ezabatu nahi duzula?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Kaixo %(site_name)s webgunetik!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Mila esker %(site_name)s webgunea erabiltzeagatik!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Helbide elektronikoa" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "%(email)s emaila egiaztatu duzu." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "email egiaztapena" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Email hau jaso duzu %(user_display)s erabiltzaileak zure helbide " "elektronikoa bere kontuarekin lotu nahi duelako %(site_domain)s orrialdean.\n" "\n" "Hau zuzena dela baieztatzeko, egin klik hemen: %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Mesedez egiaztatu zure helbide elektronikoa" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Ezabatu" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Saioa hasi" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Zure pasahitza aldatuta dago orain." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Pasahitza (berriro)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Email hau jaso duzu zuk edo beste norbaitek pasahitza berrezartzeko eskaera " "egin duelako zure kontuarentzat.\n" "Eskaera zuk egin ez baduzu mezu hau alde batera utzi dezakezu. Edo egin klik " "ondorengo estekan zure pasahitza berrezartzeko." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Ahaztu baduzu, zure erabiltzaile izena %(username)s da." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Pasahitza berrezartzeko emaila" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Zure pasahitza aldatuta dago orain." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Pasahitza berrezarri" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Zure pasahitza aldatuta dago orain." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Pasahitza berrezarri" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Kontua" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Helbide elektronikoak" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Oraingo pasahitza" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Zure email nagusiak egiaztatuta egon behar du." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Emaila" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Emaila" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Helbide elektronikoa egiaztatu" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Mesedez egiaztatu %(email)s " "%(user_display)s erabiltzailearen helbide elektroniko bat dela." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Sare sozial kontua dagoeneko beste kontu bati lotuta dago." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Egiaztapen esteka hau iraungirik dago edo baliogabea da. Mesedez eskatu egiaztapen email berri bat." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Oraindik kontu bat sortu ez baduzu, mesedez %(link)ssortu kontu " "bat%(end_link)s lehenik." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Saioa amaitu" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Ziur al zaude saioa amaitu nahi duzula?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Ezin duzu zure helbide elektroniko nagusia ezabatu (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Egiaztapen emaila bidali da %(email)s helbidera." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s emaila egiaztatu duzu." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s helbide elektronikoa ezabatu da." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s bezala hasi duzu saioa." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Saioa amaitu duzu." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Pasahitza behar bezala aldatu da." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Pasahitza behar bezala zehaztu da." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Helbide elektroniko nagusia zehaztu da." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Pasahitza aldatu" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Pasahitza ahaztu duzu?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Zure pasahitza ahaztu al duzu? Idatzi zure helbide elektronikoa hemen eta " "pasahitza berrezartzeko email bat bidaliko dizugu." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Nire pasahitza berrezarri" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Mesedez jarri gurekin kontaktuan zure pasahitza berrezartzeko arazorik " "baduzu." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Email bat bidali dizugu zure helbidea egiaztatzeko.\n" "Mesedez egin klik bertan aurkituko duzun estekan,\n" "edo jarri gurekin kontaktuan hurrengo minutuetan\n" "emailik jasotzen ez baduzu." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Token baliogabea" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Pasahitza berrezartzeko esteka baliogabea da, beharbada lehendik ere erabili " "delako. Mesedez eskatu pasahitza " "berrezartzeko email berri bat." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Zure pasahitza aldatuta dago orain." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Pasahitza zehaztu" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Pasahitza ahaztu duzu?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Kontua sortu" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Kontua sortu" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Lehendik kontu bat sortua duzu? %(link)sSaioa hasi%(end_link)s orduan." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Kontua sortu" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Ezin da konturik sortu iada" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Sentitzen dugu baina ezin da kontu berririk sortu." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Oharra" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "lehendik saioa hasita duzu %(user_display)s bezala." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Adi:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Oraingoz ez duzu helbide elektronikorik zehaztu. Helbide elektroniko bat " "gehitu beharko zenuke notifikazioak jaso ahal izateko, pasahitza " "berrezartzeko, etab." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Zure helbide elektronikoa egiaztatu" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Email bat bidali dizugu zure helbidea egiaztatzeko. Mesedez egin klik bertan " "aurkituko duzun estekan kontua sortzeko prozesua amaitzeko, edo jarri " "gurekin kontaktuan hurrengo minutuetan emailik jasotzen ez baduzu." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Webguneko atal honek zuk diozuna zarela egiaztatzea\n" "eskatzen digu. Honetarako zure helbide elektronikoa\n" "egiaztatzea beharrezkoa da. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Email bat bidali dizugu zure helbidea egiaztatzeko.\n" "Mesedez egin klik bertan aurkituko duzun estekan,\n" "edo jarri gurekin kontaktuan hurrengo minutuetan\n" "emailik jasotzen ez baduzu." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Oharra: oraindik zure helbide " "elektronikoa aldatu dezakezu." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Lotutako kontuak" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "\"token secret\"-a" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "\"token secret\"-a" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "%(email)s emaila egiaztatu duzu." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "\"token secret\"-a" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "\"token secret\"-a" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "\"secret key\"-a" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "\"secret key\"-a" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Ziur al zaude saioa amaitu nahi duzula?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "\"secret key\"-a" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Egiaztatu gabe" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "\"secret key\"-a" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Oraingo pasahitza" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "sortuta" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Arazoak sare sozialarekin logina egitean" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Arazoren bat izan da zure sare sozial kontua erabiltzen saioa hasteko " "ahaleginean." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Ondorengo zerbitzu hauetako edozein erabili dezakezu zure kontuan sartzeko:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Oraingoz ez duzu sare sozial konturik lotu kontu honekin." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Sare sozial kontu bat gehitu" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Sare sozial kontu bat gehitu" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Sare sozial kontu bat gehitu" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Baliogabetutako logina" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Lotutako kontu batekin saioa hasteko saiakera bertan behera utzi duzu. " "Oharkabean gertatu bada, mesedez saioa hasi " "berriro." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Sare sozial kontua behar bezala lotu da." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Sare sozial kontu honekin lotura ezabatu da." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Zure %(provider_name)s kontua erabiltzear zaude %(site_name)s\n" "webgunean saioa hasteko. Azken pausu bezala, mesedez osa ezazu\n" "formulario hau:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Helbide elektronikoak" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Oraingo pasahitza" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Lotutako kontuak" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Pasahitzak gutxienez {0} karaktere izan behar ditu." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Email hau jaso duzu zuk edo beste norbaitek pasahitza berrezartzeko " #~ "eskaera egin duelako zure kontuarentzat.\n" #~ "Eskaera zuk egin ez baduzu mezu hau alde batera utzi dezakezu. Edo egin " #~ "klik ondorengo estekan zure pasahitza berrezartzeko." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Helbide elektroniko hauek zure kontuari lotuta daude:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Helbide elektronikoa egiaztatu" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Mesedez hasi saioa lotutako sare sozial kontu bat\n" #~ "erabiliz, edo %(link)ssortu kontu bat%(end_link)s\n" #~ "%(site_name)s webgunean eta saioa hasi hemen:" #~ msgid "or" #~ msgstr "edo" #~ msgid "change password" #~ msgstr "pasahitza aldatu" #~ msgid "OpenID Sign In" #~ msgstr "OpenID-rekin sartu" #~ msgid "This email address is already associated with another account." #~ msgstr "Helbide elektroniko hau dagoeneko beste kontu bati lotuta dago." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Email bat bidali dizugu. Mesedez jarri gurekin kontaktuan hurrengo " #~ "minutuetan jasotzen ez baduzu." django-allauth-65.0.2/allauth/locale/fa/000077500000000000000000000000001467545753200177775ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/fa/LC_MESSAGES/000077500000000000000000000000001467545753200215645ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/fa/LC_MESSAGES/django.po000066400000000000000000001601261467545753200233740ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-08-05 09:09+0000\n" "Last-Translator: Mohammad Amin Osali \n" "Language-Team: Persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.7-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "اکنون این حساب غیرفعال است." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "امکان حذف نشانه ایمیل اصلی (%(email)s) مقدور نمی باشد." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "این نشانی ایمیل ازقبل به این حساب وصل شده." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "نشانی ایمیل یا گذرواژه نادرست است." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "یک کاربر ازقبل با این نشانی ایمیل ثبت شده است." #: account/adapter.py:62 msgid "Please type your current password." msgstr "لطفا گذرواژه کنونی‌‌ات را وارد کن." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "کد اشتباه است." #: account/adapter.py:64 msgid "Incorrect password." msgstr "رمز عبور اشتباه است." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "کلید نامعتبر است یا منقضی شده است." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "توکن بازنشانی گذرواژه نامعتبر است." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "نمی توانید بیش از %d تعداد آدرس ایمیل اضافه کنید." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "تعداد تلاش های ناموفق بیش از حد مجاز شده است. لطفا بعدا تلاش کنید." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "این نشانی ایمیل به هیچ حساب کاربری‌ای متصل نشده" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "نشانی ایمیل اصلی‌ شما باید تایید شده باشد." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "نام‌کاربری قابل استفاده نیست. لطفا از نام‌کاربری دیگری استفاده کنید." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "نام‌کاربری یا گذرواژه وارد شده نادرست است." #: account/adapter.py:741 msgid "Use your password" msgstr "از گذرواژه خود استفاده کنید" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "از برنامه تایید دومرحله ای یا کد استفاده کنید" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "از کلید امنیتی استفاده کنید" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "استفاده از ایمیل های انتخابی به عنوان آدرس های تایید شده" #: account/apps.py:11 msgid "Accounts" msgstr "حساب‌ها" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "هربار باید گذرواژه‌ی یکسانی را وارد کنی." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "گذرواژه" #: account/forms.py:93 msgid "Remember Me" msgstr "مرا به خاطر بسپار" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "نشانی ایمیل" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "ایمیل" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "نام‌کاربری" #: account/forms.py:123 msgid "Username or email" msgstr "نام‌کاربری یا ایمیل" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "ورود" #: account/forms.py:137 msgid "Forgot your password?" msgstr "گذرواژه‌ات را فراموش کرده‌ای؟" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "ایمیل (دوباره)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "تاییدیه‌ی نشانی ایمیل" #: account/forms.py:311 msgid "Email (optional)" msgstr "ایمیل (اختیاری)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "هربار باید ایمیل یکسانی وارد کنی." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "گذرواژه (دوباره)" #: account/forms.py:554 msgid "Current Password" msgstr "گذرواژه کنونی" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "گذرواژه جدید" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "گذرواژه جدید (دوباره)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "کد" #: account/models.py:26 msgid "user" msgstr "کاربر" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "نشانی ایمیل" #: account/models.py:34 msgid "verified" msgstr "تاییدشده" #: account/models.py:35 msgid "primary" msgstr "اصلی" #: account/models.py:41 msgid "email addresses" msgstr "نشانی‌های ایمیل" #: account/models.py:150 msgid "created" msgstr "ایجاد‌شده" #: account/models.py:151 msgid "sent" msgstr "ارسال شد" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "کلید" #: account/models.py:157 msgid "email confirmation" msgstr "تاییدیه‌ی ایمیل" #: account/models.py:158 msgid "email confirmations" msgstr "تاییدیه‌های ایمیل" #: headless/apps.py:7 #, fuzzy msgid "Headless" msgstr "بی نتیجه" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "امکان افزودن آدرس ایمیل به حسابی که توسط تایید دومرحله ای محافظت می شود وجود " "ندارد." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "امکان غیرفعالسازی تایید دومرحله ای مقدور نمی باشد." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "کلید محرمانه" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "گذرواژه" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "یه حساب‌کاربری با این نشانی رایانامه وجود دارد. لطفا نخست وارد آن شو، سپس " "حساب %s ات را بهش وصل کن." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "توکن نادرست" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "هیچ گذرواژه‌ای برای حساب‌ات نهاده نشده." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "حساب‌ات هیچ رایانامه‌ي تایید‌شده‌ای ندارد." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "با هریک از حساب‌های شخص سوم زیر می‌توانی به حساب‌ات وارد شوی:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "حساب اجتماعی‌اِ به یه حساب دیگر متصل شده." #: socialaccount/apps.py:9 #, fuzzy msgid "Social Accounts" msgstr "حساب‌های اجتماعی" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "فراهم‌کننده" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "فراهم‌کننده" #: socialaccount/models.py:56 #, fuzzy msgid "name" msgstr "نام" #: socialaccount/models.py:58 msgid "client id" msgstr "شناسه مشتری" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "شناسه اپ، یا کلید مصرف‌کننده" #: socialaccount/models.py:63 msgid "secret key" msgstr "کلید محرمانه" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "رمز رابک (رابط برنامه‌ی کاربردی API)، رمز مشتری، یا رمز مصرف‌کننده" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 #, fuzzy msgid "Key" msgstr "کلید" #: socialaccount/models.py:81 msgid "social application" msgstr "اپلیکیشن اجتماعی" #: socialaccount/models.py:82 msgid "social applications" msgstr "اپلیکیشن‌های اجتماعی" #: socialaccount/models.py:117 msgid "uid" msgstr "شناسه‌کاربری" #: socialaccount/models.py:119 msgid "last login" msgstr "آخرین ورود" #: socialaccount/models.py:120 msgid "date joined" msgstr "تاریخ پیوست‌شده" #: socialaccount/models.py:121 msgid "extra data" msgstr "داده اضافی" #: socialaccount/models.py:125 msgid "social account" msgstr "حساب اجتماعی" #: socialaccount/models.py:126 msgid "social accounts" msgstr "حساب‌های اجتماعی" #: socialaccount/models.py:160 msgid "token" msgstr "توکن" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) یا توکن دسترسی (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "رمز توکن" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) یا توکن تازه‌سازی (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "انقضا" #: socialaccount/models.py:174 msgid "social application token" msgstr "توکن اپلیکشن اجتماعی" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "توکن‌های اپلیکیشن اجتماعی" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "داده نامعتبر نمایه" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "ورود" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "پاسخ نامعتبر هنگام دریافت توکن درخواست از \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "پاسخ نامعتبر هنگام دریافت توکن دسترسی از \"%s\"" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "توکن درخواست‌ْای برای \"%s\" ذخیره نشده." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "توکن دسترسی‌ای برای \"%s\" ذخیره نشده." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "دسترسی به منابع خصوصی \"%s\" وجود ندارد." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "پاسخ نامعتبر هنگام دریافت توکن درخواست از \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "حساب غیرفعال" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "این حساب‌کاربری غیرفعال است." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "تایید نشانی رایانامه" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "تاییدیه‌ی رایانامه" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "رمز توکن" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "تایید" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "ورود" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "نشانی‌های رایانامه" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "نشانی‌های رایانامه زیر به حساب‌ات متصل شده‌اند:" #: templates/account/email.html:25 msgid "Verified" msgstr "تایید‌شده" #: templates/account/email.html:29 msgid "Unverified" msgstr "تایید‌نشده" #: templates/account/email.html:34 msgid "Primary" msgstr "اصلی" #: templates/account/email.html:44 msgid "Make Primary" msgstr "اصلی کردن" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "بازارسال تاییدیه" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "حذف" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "افزودن نشانی رایانامه" #: templates/account/email.html:70 msgid "Add Email" msgstr "افزودن رایانامه" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "واقعا می‌خواهی نشانی رایانامه‌ی انتخاب‌شده را حذف کنی؟" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "سپاسگزارت %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "سپاس‌گزاریم برای استفاده از %(site_name)s.\n" "‏%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "نشانی رایانامه" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "نشانی رایانامه‌ %(email)s را تایید کرده‌ای." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "تاییدیه‌ی رایانامه" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s at " #| "%(site_domain)s has given yours as an e-mail address to connect their " #| "account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "سلام،\n" "\n" "این رایانامه را دریافت کردی چون کاربر %(user_display)s نشانی رایانامه‌ات را " "برای اتصال به حساب‌اش در %(site_name)s داده.\n" "\n" "برای تایید درستی این به ‌%(activate_url)s برو.\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 #, fuzzy #| msgid "Confirm Email Address" msgid "Please Confirm Your Email Address" msgstr "تایید نشانی رایانامه" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "حذف" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "ورود" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "گذرواژه‌ات اکنون تغییر کرد." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "گذرواژه (ازنو)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "سلام،\n" "\n" "این رایانامه را دریافت کرده‌ای چون برای حساب کاربری‌ات در %(site_name)s، از " "جانب خودت یا کسی دیگر، یه گذرواژه درخواست شده.\n" "برای بازنشانی گذرواژه پیوند زیر را دنبال کن. وگرنه چشم‌پوشی از این هنگامی که " "خودت هم درخواست نکردی می‌تواند امن باشد." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "در صورت فراموشی، نام‌کاربری‌ات %(username)s است." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "رایانامه‌ی بازنشانی گذرواژه" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "گذرواژه‌ات اکنون تغییر کرد." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "بازنشانی گذرواژه" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "گذرواژه‌ات اکنون تغییر کرد." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "بازنشانی گذرواژه" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "حساب" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "نشانی‌های رایانامه" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "گذرواژه کنونی" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "نشانی رایانامه‌ی اصلی‌ات باید تاییدشده باشد." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "رایانامه" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "رایانامه" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "تایید نشانی رایانامه" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "لطفا تایید کن که %(email)s یه نشانی " "رایانامه برای کاربر %(user_display)s است." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "حساب اجتماعی‌اِ به یه حساب دیگر متصل شده." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "این پیوند تاییدیه رایانامه باطل‌شده ویا نامعتبر است. لطفا یه تاییدیه جدید رایانامه درخواست کن." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "اگر هنوز یه حساب نساختی، پس لطفا نخست %(link)sثبت‌نام%(end_link)s کن." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "خروج" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "مطمئنی می‌خواهی خارج شوی؟" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "نمی‌توانی نشانی رایانامه‌ی اصلی‌ات (%(email)s) را حذف کنی." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "رایانامه‌ی تاییدیه به %(email)s فرستاده شد." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "نشانی رایانامه‌ %(email)s را تایید کرده‌ای." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "نشانی رایانامه %(email)s حذف شد." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "با %(name)s باموفقیت وارد شدی." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "خارج شده‌ای." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "گذرواژه باموفقیت تغییر کرد." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "گذرواژه باموفقیت نهاده شد." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "نشانی رانامه اصلی نهاده شد." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "تغییر گذرواژه" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "گذرواژه‌ات را فراموش کرده‌ای؟" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "گذرواژه‌ات را فراموش کرده‌ای؟ نشانی رایانامه‌ات را در زیر درج کن؛ ما رایانامه‌ی " "بازنشانی گذرواژه را برایت خواهیم فرستاد." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "درخواست بازنشانی" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "اگر مشکلی در بازنشانی گذرواژه‌ات داری، لطفا با ما تماس بگیر." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "ما یه رایانامه تاییدیه بهت فرستادیم؛ لطفا روی پیوند درونش کلیک کن. اگر تا " "دقایقی دیگر دریافتش نکردی با ما تماس بگیر." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "توکن نادرست" #: templates/account/password_reset_from_key.html:18 #, fuzzy, python-format #| msgid "" #| "The password reset link was invalid, possibly because it has already been " #| "used. Please request a new password " #| "reset." msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "پیوند بازنشانی گذرواژه نادرست است؛ شاید قبلا استفاده شده. لطفا یه بازنشان جدید گذرواژهدرخواست کن." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "گذرواژه‌ات اکنون تغییر کرد." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "نهادن گذرواژه" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "گذرواژه‌ات را فراموش کرده‌ای؟" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "ثبت‌نام" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "ثبت نام" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "ازقبل یه حساب داری؟ پس لطفا %(link)sورود%(end_link)s کن." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "ثبت نام" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "توقف ثبت‌نام" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "متاسفیم، ولی اکنون ثبت‌نام متوقف شده." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "توجه" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "ازقبل با %(user_display)s وارد شده‌ای." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "هشدار:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "اکنون هیچ نشانی رایانامه‌ی نهادیده‌ای نداری. درواقع باید یه نشانی رایانامه " "بافزایی تا بتوانی اعلان‌ها، بازنشان گذرواژه و غیره را دریافت کنی." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "تایید نشانی رایانامه" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "یه رایانامه تاییدیه بهت فرستادیم. پیوند درونش را برای کامل کردن فرایند " "ثبت‌نام دنبال کن. اگر تا چند دقیقه‌ی دیگر دریافتش نکردی، لطفا با ما تماس بگیر." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "این بخش از سایت نیاز دارد تایید کنیم شما کسی که ادعا کرده‌‌ای هستی.برای همین، " "نیازد داریم مالکیتت بر نشانی رایانامه‌ات را تایید کنی." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "ما یه رایانامه تاییدیه بهت فرستادیم؛ لطفا روی پیوند درونش کلیک کن. اگر تا " "دقایقی دیگر دریافتش نکردی با ما تماس بگیر." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "توجه: هنوز می‌توانی تعویض نشانی " "رایانامه کنی." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "اتصال‌های حساب" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "رمز توکن" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "رمز توکن" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "نشانی رایانامه‌ %(email)s را تایید کرده‌ای." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "رمز توکن" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "رمز توکن" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "کلید محرمانه" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "کلید محرمانه" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "مطمئنی می‌خواهی خارج شوی؟" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "کلید محرمانه" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "تایید‌نشده" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "کلید محرمانه" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "گذرواژه کنونی" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "ایجاد‌شده" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "ناموفق در ورود با شبکه اجتماعی" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "یه خطا هنگام سعی برای ورود با حساب شبکه‌ی اجتماعی‌ات رخ داد." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "با هریک از حساب‌های شخص سوم زیر می‌توانی به حساب‌ات وارد شوی:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "اکنون هیچ حساب شبکه‌ی اجتماعی‌ای به این حساب متصل نشده." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "افزودن یه حساب سوم شخص" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "افزودن یه حساب سوم شخص" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "افزودن یه حساب سوم شخص" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "لغو ورود" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "ورودت به سایت‌مان با یکی از حساب‌هایت را لغو کردی. اگر اشتباهی شده، لطفا اقدام " "به ورود کن." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "حساب اجتماعی‌اِ متصل شد." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "حساب اجتماعی‌اِ قطع‌ارتباط شد." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "چند قدمی ورود به %(site_name)s با حساب‌ات %(provider_name)s هستی. در گام آخر، " "لطفا فرم زیر را کامل کن:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "نشانی‌های رایانامه" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "گذرواژه کنونی" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "اتصال‌های حساب" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "گذرواژه باید حداقل {0} کاراکتر باشد." #, fuzzy, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "سلام،\n" #~ "\n" #~ "این رایانامه را دریافت کرده‌ای چون برای حساب کاربری‌ات در %(site_name)s، " #~ "از جانب خودت یا کسی دیگر، یه گذرواژه درخواست شده.\n" #~ "برای بازنشانی گذرواژه پیوند زیر را دنبال کن. وگرنه چشم‌پوشی از این هنگامی " #~ "که خودت هم درخواست نکردی می‌تواند امن باشد." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "نشانی‌های رایانامه زیر به حساب‌ات متصل شده‌اند:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "تایید نشانی رایانامه" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "لطفا با یکی از حساب‌های شخص سوم موجودت وارد شو. یا در %(site_name)sثبت‌نام کن و از زیر وارد شو:" #~ msgid "or" #~ msgstr "یا" #~ msgid "change password" #~ msgstr "تغییر گذرواژه" #~ msgid "OpenID Sign In" #~ msgstr "ورودبا OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "این نشانی رایانامه ازقبل به حساب دیگری وصل شده." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "بهت یه رایانامه فرستادیم. اگر تا چند دقیقه‌ی دیگر دریافتش نکردی باهامون " #~ "تماس بگیر." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "اطلاعات داده شده درست نیست." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "نام‌کاربری تنها می‌تواند شامل حروف، اعداد، و @/./+/-/_. باشد" #~ msgid "This username is already taken. Please choose another." #~ msgstr "این نام‌کاربری قبلا گرفته شده. لطفا یکی دیگر انتخاب کن." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "ورود با Shopify" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "تایید کرده‌ای که %(email)s یه نشانی " #~ "رایانامه برای کاربر %(user_display)s است." django-allauth-65.0.2/allauth/locale/fi/000077500000000000000000000000001467545753200200075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/fi/LC_MESSAGES/000077500000000000000000000000001467545753200215745ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/fi/LC_MESSAGES/django.po000066400000000000000000001473001467545753200234030ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:30+0200\n" "Last-Translator: Anonymous User \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Translated-Using: django-rosetta 0.7.6\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Tämä tili on poistettu käytöstä." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Et voi poistaa ensisijaista sähköpostiosoitettasi (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Sähköpostiosoite on jo liitetty tähän tilliin." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Annettu sähköposti tai salasana ei ole oikein." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Tämä sähköpostiosoite on jo käytössä." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Ole hyvä ja anna nykyinen salasanasi." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Nykyinen salasana" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Virheellinen tunniste" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Salasanan uusimistarkiste ei kelpaa." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Tiliisi ei ole liitetty vahvistettua sähköpostiosoitetta." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Liian monta virheellistä kirjautumisyritystä. Yritä myöhemmin uudelleen." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Sähköpostiosoite ei vastaa yhtäkään käyttäjätiliä." #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Ensisijaisen sähköpostiosoiteen tulee olla vahvistettu." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Käyttäjänimeä ei voi käyttää. Valitse toinen käyttäjänimi." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Annettu käyttäjänimi tai salasana ei ole oikein." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Salasana unohtunut?" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "salainen avain" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Ensisijaisen sähköpostiosoiteen tulee olla vahvistettu." #: account/apps.py:11 msgid "Accounts" msgstr "Tili" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Salasanojen tulee olla samat." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Salasana" #: account/forms.py:93 msgid "Remember Me" msgstr "Muista minut" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Sähköpostiosoite" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Sähköposti" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Käyttäjänimi" #: account/forms.py:123 msgid "Username or email" msgstr "Käyttäjänimi tai sähköposti" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Käyttäjätunnus" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Salasana unohtunut?" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "Sähköpostiosoite (valinnainen)" #: account/forms.py:303 #, fuzzy #| msgid "email confirmation" msgid "Email address confirmation" msgstr "sähköpostivarmistus" #: account/forms.py:311 msgid "Email (optional)" msgstr "Sähköpostiosoite (valinnainen)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Salasanojen tulee olla samat." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Salasana (uudestaan)" #: account/forms.py:554 msgid "Current Password" msgstr "Nykyinen salasana" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Uusi salasana" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Uusi salasana (uudestaan)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "käyttäjä" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "sähköpostiosoite" #: account/models.py:34 msgid "verified" msgstr "vahvistettu" #: account/models.py:35 msgid "primary" msgstr "ensisijainen" #: account/models.py:41 msgid "email addresses" msgstr "sähköpostiosoitteet" #: account/models.py:150 msgid "created" msgstr "luotu" #: account/models.py:151 msgid "sent" msgstr "lähetetty" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "avain" #: account/models.py:157 msgid "email confirmation" msgstr "sähköpostivarmistus" #: account/models.py:158 msgid "email confirmations" msgstr "sähköpostivarmistukset" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "salainen avain" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Salasana" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Sähköpostiosoite on jo liitetty olemassaolevaan tiliin. Kirjaudu ensin " "kyseiseen tiliin ja liitä %s-tilisi vasta sitten." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Virheellinen tunniste" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Tilillesi ei ole asetettu salasanaa." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Tiliisi ei ole liitetty vahvistettua sähköpostiosoitetta." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "Voit kirjautua käyttäen seuraavia kirjautumispalveluita:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Sosiaalisen median tili on jo liitetty toiseen tiliin." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sosiaalisen median tilit" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "tarjoaja" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "tarjoaja" #: socialaccount/models.py:56 msgid "name" msgstr "nimi" #: socialaccount/models.py:58 msgid "client id" msgstr "asiakas id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Sovellus ID tai kuluttajan avain" #: socialaccount/models.py:63 msgid "secret key" msgstr "salainen avain" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API:n, asiakkaan tai kuluttajan salaisuus" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Avain" #: socialaccount/models.py:81 msgid "social application" msgstr "sosiaalinen applikaatio" #: socialaccount/models.py:82 msgid "social applications" msgstr "sosiaaliset applikaatiot" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "viimeisin sisäänkirjautuminen" #: socialaccount/models.py:120 msgid "date joined" msgstr "liittymispäivämäärä" #: socialaccount/models.py:121 msgid "extra data" msgstr "lisätiedot" #: socialaccount/models.py:125 msgid "social account" msgstr "sosiaalisen median tili" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sosiaalisen median tilit" #: socialaccount/models.py:160 msgid "token" msgstr "" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "vanhenee" #: socialaccount/models.py:174 msgid "social application token" msgstr "" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Käyttäjätunnus" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Virheellinen vastaus palvelusta \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Virhe hankittaessa käyttöoikeustunnistetta palvelusta \"%s\"" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Virheellinen vastaus palvelusta \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Tili poissa käytöstä" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Tämä tili ei ole käytössä." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Vahvista sähköpostiosoite" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "sähköpostivarmistus" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Vahvista" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Kirjaudu sisään" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Sähköpostiosoitteet" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Seuraavat sähköpostiosoitteet on liitetty tiliisi:" #: templates/account/email.html:25 msgid "Verified" msgstr "Vahvistettu" #: templates/account/email.html:29 msgid "Unverified" msgstr "Vahvistamaton" #: templates/account/email.html:34 msgid "Primary" msgstr "Ensisijainen" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Aseta ensisijaiseksi" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Lähetä vahvistus uudelleen" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Poista" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Lisää sähköpostiosoite" #: templates/account/email.html:70 msgid "Add Email" msgstr "Lisää sähköposti" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Haluatko varmasti poistaa valitun sähköpostiosoitteen?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Terve palvelusta %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Kiitos, kun käytät %(site_name)s palvelua!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Sähköpostiosoite" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Sähköpostiosoite %(email)s on vahvistettu." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "sähköpostivarmistus" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Sait tämän viestin, koska käyttäjä %(user_display)s palvelusta " "%(site_domain)s antoi sähköpostiosoitteesi liitettäväksi tiliinsä.\n" "\n" "Vahvistaaksesi tiedot oikeiksi mene osoitteeseen %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Vahvista sähköpostiosoitteesi" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Poista" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Kirjaudu sisään" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Salasanasi on nyt vaihdettu." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Salasana (uudestaan)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Sait tämän sähköpostin, koska sinä tai joku muu on pyytänyt salasasi " "uusimista palvelussa %(site_domain)s.\n" "Tämän viestin voi jättää huomiotta, jos et pyytänyt salasanan uusimista. " "Klikkaa alla olevaa linkkiä uusiaksesi salasanasi." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Muistathan, että käyttäjätunnuksesi on %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Salasanan uusimissähköposti" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Salasanasi on nyt vaihdettu." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Salasanan uusiminen" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Salasanasi on nyt vaihdettu." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Salasanan uusiminen" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Tili" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Sähköpostiosoitteet" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Nykyinen salasana" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Ensisijaisen sähköpostiosoiteen tulee olla vahvistettu." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Sähköposti" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Sähköposti" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Vahvista sähköpostiosoite" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Vahvista, että %(email)s on käyttäjän " "%(user_display)s sähköpostiosoite." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Sosiaalisen median tili on jo liitetty toiseen tiliin." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Tämä sähköpostiosoitteen vahvistuslinkki on vanhentunut tai muuten " "käyttökelvoton. Voit kuitenkin pyytää uuden " "vahvistuslinkin sähköpostiosoitteellesi." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Jos et ole luonut vielä tiliä, niin %(link)srekisteröidy%(end_link)s ensin." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Kirjaudu ulos" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Haluatko varmasti kirjautua ulos?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Et voi poistaa ensisijaista sähköpostiosoitettasi (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Vahvistusviesti on lähetetty osoitteeseen %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Sähköpostiosoite %(email)s on vahvistettu." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Poistettiin sähköpostiosoite %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Kirjauduttiin sisään käyttäjänä %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Kirjauduit ulos." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Salasana vaihto onnistui." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Salasana asetettiin." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Ensisijainen sähköpostiosoite asetettiin." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Vaihda salasana" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Salasana unohtunut?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Unohditko salasanasi? Anna sähköpostiosoitteesi ja lähetämme sinulle " "sähköpostin, jonka avulla voit uusia sen." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Salasanan uusiminen" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Ota meihin yhteyttä, jos sinulla on ongelmia salasanasi uusimisessa." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Olemme lähettäneet sinulle sähköpostivahvistuksen. Klikkaa sähköpostissa " "olevaa linkkiä vahvistaaksesi sähköpostiosoitteesi. Ota meihin yhteyttä, jos " "et saanut vahvistusviestiä muutaman minuutin sisällä." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Virheellinen tunniste" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Salasanan uusimislinkki ei toiminut. Tämä voi tapahtua, jos linkki on jo " "käytetty. Voit kuitenkin uusia salasanan " "uusimisen." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Salasanasi on nyt vaihdettu." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Aseta salasana" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Salasana unohtunut?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Rekisteröidy" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Rekisteröidy" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Onko sinulla jo tili? %(link)sKirjaudu sisään%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Rekisteröidy" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Rekisteröityminen on poissa käytöstä." #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Valitettavasti rekisteröityminen on pois käytöstä." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Huomio" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "olet jo kirjautunut käyttäjänä %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Varoitus:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Et ole asettanut sähköpostiosoitetta. Tämä tulisi tehdä, jotta voit saada " "ilmoituksia, uusia salasanasi jne." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Vahvista sähköpostiosoitteesi" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Lähetimme sinulle sähköpostin vahvistusviestin. Klikkaa sähköpostissa olevaa " "linkkiä viimeistelläksesi rekisteröitymisprosessin. Ota meihin yhteyttä, jos " "et saanut vahvistusviestiä muutaman minuutin sisällä." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Tämä osa palvelua vaatii, että tiedämme kuka olet. Tämän takia sinun pitää " "vahvistaa omistavasi ilmoittamasi sähköpostiosoite." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Olemme lähettäneet sinulle sähköpostivahvistuksen. Klikkaa sähköpostissa " "olevaa linkkiä vahvistaaksesi sähköpostiosoitteesi. Ota meihin yhteyttä, jos " "et saanut vahvistusviestiä muutaman minuutin sisällä." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Huomio: voit edelleen vaihtaa " "sähköpostiosoitteesi." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Liitetyt tilit" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Sähköpostiosoite %(email)s on vahvistettu." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "salainen avain" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "salainen avain" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Haluatko varmasti kirjautua ulos?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "salainen avain" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Vahvistamaton" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "salainen avain" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Nykyinen salasana" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "luotu" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Sosiaalisen median tilillä kirjautuminen epäonnistui" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Tapahtui virhe yritettäessä kirjautua käyttäen sosiaalisen median tiliä." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Voit kirjautua käyttäen seuraavia kirjautumispalveluita:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Tiliisi ei ole liitetty yhtäkään sosiaalisen median tiliä." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Lisää kolmannen osapuolen tili" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Lisää kolmannen osapuolen tili" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Lisää kolmannen osapuolen tili" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Sisäänkirjautuminen keskeytettiin" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Keskeytit sisäänkirjautumisen olemassaolevalle tilillesi. Jos tämä oli " "vahinko niin kirjaudu sisään." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Sosiaalisen median tili liitettiin." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Sosiaalisen median tili on poistettu käytöstä." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Olet aikeissa käyttää %(provider_name)s-tiliäsi kirjautuaksesi palveluun\n" "%(site_name)s. Täytä vielä seuraava lomake:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Sähköpostiosoitteet" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Nykyinen salasana" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Liitetyt tilit" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Salasanan tulee olla vähintään {0} merkkiä pitkä." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Sait tämän sähköpostin, koska sinä tai joku muu on pyytänyt salasasi " #~ "uusimista palvelussa %(site_domain)s.\n" #~ "Tämän viestin voi jättää huomiotta, jos et pyytänyt salasanan uusimista. " #~ "Klikkaa alla olevaa linkkiä uusiaksesi salasanasi." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Seuraavat sähköpostiosoitteet on liitetty tiliisi:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Vahvista sähköpostiosoite" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Kirjaudu sisään käyttäen kirjautumispalvelua tai rekisteröi %(site_name)s-tili ja kirjaudu " #~ "sisään alla olevalla lomakkeella:" #~ msgid "or" #~ msgstr "tai" #~ msgid "change password" #~ msgstr "vaihda salasanaa" #~ msgid "OpenID Sign In" #~ msgstr "OpenID kirjautuminen" #~ msgid "This email address is already associated with another account." #~ msgstr "Sähköpostiosoite on jo liitetty toiseen tiliin." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Olemme lähettäneet sinulle sähköpostia. Ota meihin yhteyttä, jos et saa " #~ "sitä muutaman minuutin sisällä." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Kirjautumistiedot eivät ole oikein." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Käyttäjänimi saa sisältää vain kirjaimia, numeroita ja erikoismerkkejä " #~ "@/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Käyttäjänimi on käytössä. Valitse toinen käyttäjänimi." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Kirjaudu sisään" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Olet vahvistanut, että %(email)s on " #~ "sähköpostiosoite käyttäjälle %(user_display)s." django-allauth-65.0.2/allauth/locale/fr/000077500000000000000000000000001467545753200200205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/fr/LC_MESSAGES/000077500000000000000000000000001467545753200216055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/fr/LC_MESSAGES/django.po000066400000000000000000001563551467545753200234260ustar00rootroot00000000000000# DJANGO-ALLAUTH. # Copyright (C) 2016 # This file is distributed under the same license as the django-allauth package. # # Translators: # Steve Kossouho , 2016. # Gilou , 2019 # msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-08-11 08:09+0000\n" "Last-Translator: Olivier Debauche \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.7-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Ce compte est actuellement désactivé." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Vous ne pouvez pas retirer votre adresse e-mail principale." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "L'adresse e-mail est déjà associée à votre compte." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "L’adresse e-mail ou le mot de passe sont incorrects." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Un autre utilisateur utilise déjà cette adresse e-mail." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Merci d'indiquer votre mot de passe actuel." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Code incorrect." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Mot de passe incorrect." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Clé invalide ou expirée." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Le jeton de réinitialisation de mot de passe est invalide." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Vous ne pouvez pas ajouter plus de %d adresses e-mail." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Trop de tentatives de connexion échouées. Veuillez réessayer ultérieurement." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Cette adresse e-mail n'est pas associée à un compte utilisateur" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Votre adresse e-mail principale doit être vérifiée." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Ce pseudonyme ne peut pas être utilisé. Veuillez en choisir un autre." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Le pseudo et/ou le mot de passe sont incorrects." #: account/adapter.py:741 msgid "Use your password" msgstr "Utilisez votre mot de passe" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Utilisez une application d'authentification ou un code" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Utilisez une clé secrète" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Marquer les adresses e-mail sélectionnées comme vérifiées" #: account/apps.py:11 msgid "Accounts" msgstr "Comptes" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Vous devez saisir deux fois le même mot de passe." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Mot de passe" #: account/forms.py:93 msgid "Remember Me" msgstr "Se souvenir de moi" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Adresse e-mail" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nom d'utilisateur" #: account/forms.py:123 msgid "Username or email" msgstr "Nom d'utilisateur ou e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Identifiant" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Mot de passe oublié ?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (confirmation)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Confirmation d'adresse e-mail" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (facultatif)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Vous devez saisir deux fois le même e-mail." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Mot de passe (confirmation)" #: account/forms.py:554 msgid "Current Password" msgstr "Mot de passe actuel" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nouveau mot de passe" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nouveau mot de passe (confirmation)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Code" #: account/models.py:26 msgid "user" msgstr "utilisateur" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "adresse e-mail" #: account/models.py:34 msgid "verified" msgstr "vérifiée" #: account/models.py:35 msgid "primary" msgstr "principale" #: account/models.py:41 msgid "email addresses" msgstr "adresses e-mail" #: account/models.py:150 msgid "created" msgstr "créé" #: account/models.py:151 msgid "sent" msgstr "envoyé" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "clé" #: account/models.py:157 msgid "email confirmation" msgstr "confirmation par e-mail" #: account/models.py:158 msgid "email confirmations" msgstr "confirmations par e-mail" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Vous ne pouvez pas ajouter une adresse e-mail à un compte protégé par " "l'authentification à deux facteurs." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Vous ne pouvez pas désactiver l'authentification à deux facteurs." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Vous ne pouvez pas générer de codes de récupération sans avoir activé " "l'authentification à deux facteurs." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Vous ne pouvez pas activer l'authentification à deux facteurs tant que vous " "n'avez pas vérifié votre adresse e-mail." #: mfa/adapter.py:141 msgid "Master key" msgstr "Clé principale" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Clé de secours" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Clé n°{number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Codes de récupération" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Authentificateur TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Code de l'authentificateur" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Sans mot de passe" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "L'activation des opérations sans mot de passe vous permet de vous connecter " "en utilisant seulement cette clé/appareil, mais demande des exigences plus " "élevées comme les informations biométriques ou un code PIN." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Un compte existe déjà avec cette adresse e-mail. Merci de vous connecter au " "préalable avec ce compte, et ensuite connecter votre compte %s." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Mauvais jeton d'identification." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Vous devez d'abord définir le mot de passe de votre compte." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Vous devez d'abord associer une adresse e-mail à votre compte." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Vous ne pouvez pas déconnecter votre dernier compte tiers restant." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Ce compte social est déjà connecté à un autre compte." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Comptes sociaux" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "fournisseur" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID du fournisseur" #: socialaccount/models.py:56 msgid "name" msgstr "nom" #: socialaccount/models.py:58 msgid "client id" msgstr "id client" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID de l'app ou clé de l'utilisateur" #: socialaccount/models.py:63 msgid "secret key" msgstr "clé secrète" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Secret de l'API, secret du client, ou secret de l'utilisateur" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Clé" #: socialaccount/models.py:81 msgid "social application" msgstr "application sociale" #: socialaccount/models.py:82 msgid "social applications" msgstr "applications sociales" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "dernière connexion" #: socialaccount/models.py:120 msgid "date joined" msgstr "date d'inscription" #: socialaccount/models.py:121 msgid "extra data" msgstr "données supplémentaires" #: socialaccount/models.py:125 msgid "social account" msgstr "compte social" #: socialaccount/models.py:126 msgid "social accounts" msgstr "comptes sociaux" #: socialaccount/models.py:160 msgid "token" msgstr "jeton" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ou jeton d'accès (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "jeton secret" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ou jeton d'actualisation (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "expire le" #: socialaccount/models.py:174 msgid "social application token" msgstr "jeton de l'application sociale" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "jetons de l'application sociale" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Données de profil incorrectes" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Identifiant" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Annuler" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Réponse invalide lors de l'obtention du jeton de requête de \"%s\". La " "réponse était : %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Réponse invalide lors de l'obtention du jeton d'accès depuis \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Aucun jeton de requête sauvegardé pour \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Aucun jeton d'accès sauvegardé pour \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Impossible d'accéder aux ressources privées de \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Réponse invalide lors de l'obtention du jeton de requête de \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Compte inactif" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Ce compte est inactif." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Confirmer l'accès" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Veuillez vous réauthentifier pour protéger votre compte." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Options alternatives" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "Confirmation par e-mail" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Saisissez un code d'authentification :" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Nous avons envoyé un code à %(email_link)s. Ce code expire rapidement, donc " "veuillez l'entrer rapidement." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Confirmer" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Connexion" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Entrez le code de connexion" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Adresses e-mail" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Les adresses e-mail suivantes sont associées à votre compte :" #: templates/account/email.html:25 msgid "Verified" msgstr "Vérifiée" #: templates/account/email.html:29 msgid "Unverified" msgstr "Non vérifiée" #: templates/account/email.html:34 msgid "Primary" msgstr "Principale" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Rendre principale" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Renvoyer le message de vérification" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Retirer" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Ajouter une adresse e-mail" #: templates/account/email.html:70 msgid "Add Email" msgstr "Ajouter un e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Voulez-vous vraiment retirer cette adresse e-mail ?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Vous recevez cet email car vous ou quelqu'un d'autre a demandé à créer\n" "un compte en utilisant cette adresse e-mail :\n" "\n" "%(email)s\n" "\n" "Cependant, un compte utilisant cette adresse existe déjà. Au cas où vous " "auriez\n" "oublié, merci d'utiliser la fonction de récupération de mot de passe pour\n" "récupérer votre compte :\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Ce compte existe déjà" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Bonjour, c'est %(site_name)s !" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Merci d'utiliser %(site_name)s !\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Vous recevez cet e-mail car la modification suivante a été apportée à votre " "compte :" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Si vous ne reconnaissez pas ce changement, veuillez prendre immédiatement " "les mesures de sécurité qui s'imposent. La modification de votre compte " "provient de :\n" "\n" "- L'adresse IP : %(ip)s\n" "- Navigateur : %(user_agent)s\n" "- Date : %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Votre adresse e-mail a été modifiée de %(from_email)s à %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E-mail modifié" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Votre e-mail a été confirmé." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Confirmation par e-mail" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Vous recevez cet e-mail car l'utilisateur %(user_display)s a indiqué votre " "adresse pour se connecter à son compte sur %(site_domain)s.\n" "\n" "Pour confirmer que vous en êtes bien le propriétaire, allez à " "%(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Votre code de connexion est indiqué ci-dessous. Veuillez le saisir dans la " "fenêtre ouverte de votre navigateur." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Confirmez votre adresse e-mail" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "L'adresse e-mail %(deleted_email)s a été retirée de votre compte." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "E-mail retiré" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Votre code de connexion est indiqué ci-dessous. Veuillez le saisir dans la " "fenêtre ouverte de votre navigateur." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Cet email peut être ignoré si vous n'avez pas effectué cette action." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Code de connexion" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Votre mot de passe a été modifié." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Mot de passe modifié" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Vous recevez cet e-mail car vous ou quelqu'un d'autre a demandé une " "réinitialisation de mot de passe pour votre compte utilisateur.\n" "Vous pouvez simplement ignorer ce message si vous n'êtes pas à l'origine de " "cette demande. Sinon, cliquez sur le lien ci-dessous pour réinitialiser " "votre mot de passe." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "" "Au cas où vous l'auriez oublié, votre nom d'utilisateur est %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail de réinitialisation de mot de passe" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Votre mot de passe a été réinitialisé." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Réinitialisation du mot de passe" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Votre mot de passe a été défini." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Définition du mot de passe" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Vous recevez cet email car vous, ou quelqu'un d'autre, a essayé d'accéder à " "un compte avec l'email %(email)s. Cependant, nous ne disposons pas de ce " "compte dans nos bases de données." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Si c'était vous, vous pouvez vous inscrire en utilisant le lien ci-dessous." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Compte inconnu" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Adresse e-mail" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "E-mail actuel" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Changer pour" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Votre adresse e-mail est toujours en attente de vérification." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Annuler la modification" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Changer pour" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Changer d'e-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Confirmer l'adresse e-mail" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Merci de confirmer que %(email)s est " "l'adresse e-mail de %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Impossible de confirmer %(email)s car il est déjà confirmé par un autre " "compte." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Ce lien de confirmation d'adresse e-mail a expiré ou n'est pas valide. " "Veuillez lancer une nouvelle demande de " "confirmation." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Si vous n'avez pas encore créé de compte, merci de vous " "%(link)senregistrer%(end_link)s au préalable." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Se connecter avec une clé d'accès" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "M'envoyer un code de connexion" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Se déconnecter" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Êtes-vous sûr(e) de vouloir vous déconnecter ?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "" "Vous ne pouvez pas retirer votre adresse e-mail principale (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "E-mail de confirmation envoyé à %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Vous avez confirmé %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Adresse e-mail %(email)s retirée." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Connexion avec %(name)s réussie." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Vous êtes déconnecté(e)." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Un code de connexion a été envoyé à %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Mot de passe modifié avec succès." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Mot de passe défini avec succès." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Adresse e-mail principale enregistrée." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Modifier le mot de passe" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Mot de passe oublié ?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Mot de passe oublié ? Indiquez votre adresse e-mail ci-dessous et nous vous " "enverrons un e-mail pour le réinitialiser." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Réinitialiser mon mot de passe" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Merci de nous contacter si vous ne parvenez pas à réinitialiser votre mot de " "passe." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Nous vous avons envoyé un e-mail. Si vous ne l'avez pas reçu, veuillez " "vérifier votre dossier de spam. Sinon, contactez-nous si vous ne le recevez " "pas dans quelques minutes." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Mauvais jeton d'identification" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Le lien de réinitialisation du mot de passe est invalide. Il a peut être " "déjà été utilisé. Veuillez faire une nouvelle demande de réinitialisation de mot de passe." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Votre mot de passe a été modifié." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Définir un mot de passe" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Saisissez votre mot de passe :" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Vous recevrez un email avec un code spécial pour vous connecter sans mot de " "passe." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Demander un code" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Autres options de connexion" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Inscription" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Création de compte" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "Vous avez déjà un compte ? Vous pouvez donc %(link)svous " "connecter%(end_link)s." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "Se connecter avec une clé d'accès" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Création de compte" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Autres options de connexion" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Inscriptions fermées" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Nous sommes désolés, mais les inscriptions sont actuellement fermées." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Remarque" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Vous êtes déjà connecté en tant que %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Attention :" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Vous n'avez aucune adresse e-mail associée à votre compte. Vous devriez " "ajouter une adresse e-mail pour pouvoir recevoir des notifications, " "réinitialiser votre mot de passe, etc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Vérifiez votre adresse e-mail" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Nous vous avons envoyé un e-mail pour validation. Cliquez sur le lien fourni " "dans l'e-mail pour terminer l'inscription. Si vous ne voyez pas l'e-mail de " "vérification dans votre boîte de réception, vérifiez votre dossier spam. " "Merci de nous contacter si vous ne le recevez pas d'ici quelques minutes." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Pour accéder à cette partie du site, il faut d'abord que\n" "nous ayons vérifié qui vous indiquez être. Pour cela, vous devez prouver\n" "que vous êtes bien le propriétaire de l'adresse e-mail que vous nous avez " "indiquée. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Nous vous avons envoyé un e-mail de vérification.\n" "Merci de cliquer sur le lien inclus dans ce courriel. Si vous ne voyez pas " "l'e-mail de vérification dans votre boîte de réception, vérifiez votre " "dossier spam.\n" "Contactez-nous si vous ne l'avez pas reçu d'ici quelques minutes." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Remarque : vous pouvez toujours changer votre adresse e-mail." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Messages :" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu :" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Comptes associés" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Authentification à deux facteurs" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sessions" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Votre compte est protégé par l'authentification à deux facteurs. Veuillez " "saisir un code d'authentification :" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "Un nouveau jeu de codes de récupération pour l'authentification à deux " "facteurs a été généré." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Nouveaux codes de récupération générés" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Application d'authentification activée." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Application d'authentification activée" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Application d'authentification désactivée." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Application d'authentification désactivée" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Une nouvelle clé de sécurité a été ajoutée." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Clé de sécurité ajoutée" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Une clé de sécurité a été retirée." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Clé de sécurité retirée" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Application d'authentification" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" "L'authentification à l'aide d'une application d'authentification est active." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Aucune application d'authentification active." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Désactiver" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Activer" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Clés de sécurité" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Vous avez ajouté %(count)s clé de sécurité." msgstr[1] "Vous avez ajouté %(count)s clés de sécurité." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Aucune clé de sécurité n'a été ajoutée." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Gérer" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Ajouter" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Codes de récupération" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Il y a %(unused_count)s code de récupération disponible sur %(total_count)s." msgstr[1] "" "Il y a %(unused_count)s codes de récupération disponibles sur " "%(total_count)s." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Aucun code de récupération défini." #: templates/mfa/index.html:96 msgid "View" msgstr "Afficher" #: templates/mfa/index.html:102 msgid "Download" msgstr "Télécharger" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Générer" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Un nouveau jeu de codes de récupération a été généré." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Clé de sécurité ajoutée." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Clé de sécurité enlevée." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Saisissez un code d'authentification :" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Vous êtes sur le point de générer un nouveau jeu de codes de récupération " "pour votre compte." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Cette action invalidera vos codes existants." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Êtes-vous sûr(e) ?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Codes inutilisés" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Télécharger les codes" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Générer de nouveaux codes" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Activer l'application d'authentification" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Pour protéger votre compte avec l'authentification à deux facteurs, scannez " "le code QR ci-dessous avec votre application d'authentification. Ensuite, " "saisissez le code de vérification généré par l'application ci-dessous." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Secret d'authentification" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Vous pouvez stocker ce secret et l'utiliser pour réinstaller votre " "application d'authentification ultérieurement." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Désactiver l'application d'authentification" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Vous êtes sur le point de désactiver l'authentification basée sur " "l'application d'authentification. Êtes-vous sûr(e) ?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Ajouter une clé de sécurité" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Enlever une clé de sécurité" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Êtes-vous sûr de vouloir supprimer cette clé de sécurité ?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Utilisation" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Clé de sécurité" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "clé de sécurité" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Cette clé n'indique pas si c'est une clé de sécurité." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Non spécifiée" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Ajoutée à %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Dernière utilisation à %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Modifier" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Modifier la clé de sécurité" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Enregistrer" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "Clé de sécurité" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "créé" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Cette fonctionnalité nécessite JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Échec de la connexion via réseau social" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Une erreur est survenue lors de la tentative de connexion à votre compte de " "réseau social." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Vous pouvez vous connecter à votre compte en utilisant l'un des comptes " "tiers suivants :" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Aucun compte social n'est actuellement associé à ce compte." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Ajouter un compte tiers" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "Un compte tiers de %(provider)s a été associé à votre compte." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Compte tiers ajouté" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "Un compte tiers de %(provider)s a été dissocié de votre compte." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Compte tiers dissocié" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Connecter %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Vous êtes sur le point de connecter un nouveau compte tiers de %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Connexion via %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Vous êtes sur le point de vous connecter en utilisant un compte tiers de " "%(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Continuer" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Connexion annulée" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Vous avez annulé la connexion à notre site depuis l'un de vos comptes de " "réseau social. S'il s'agit d'une erreur, merci de vous reconnecter." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Le compte social a bien été connecté." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Le compte social a été déconnecté." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Vous êtes sur le point de vous connecter via votre compte %(provider_name)s\n" "au site %(site_name)s. Merci de compléter le formulaire suivant pour " "confirmer la connexion :" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Ou utilisez un service tiers" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Déconnecté de toutes les autres sessions." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Commencé à" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "Adresse IP" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Navigateur" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Vu pour la dernière fois à" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Actuel" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Déconnecter les autres sessions" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Sessions utilisateur" #: usersessions/models.py:92 msgid "session key" msgstr "Clé de session" #~ msgid "Account Connection" #~ msgstr "Connexion au compte" #, fuzzy #~ msgid "Use security key or device" #~ msgstr "Utilisez votre clé de sécurité ou appareil" #, fuzzy #~ msgid "Add Security Key or Device" #~ msgstr "Ajouter une clé de sécurité ou un appareil" #~ msgid "Add key or device" #~ msgstr "Ajouter une clé ou un appareil" #, fuzzy #~ msgid "Security Keys and Devices" #~ msgstr "Clés de sécurité et appareils" #, fuzzy #~ msgid "You have not added any security keys/devices." #~ msgstr "Vous n'avez pas ajouté de clés de sécurité ou d'appareils." #, fuzzy #~ msgid "Edit Security Key or Device" #~ msgstr "Modifier la clé de sécurité ou l'appareil" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Le mot de passe doit contenir au minimum {0} caractères." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "\"Vous recevez cet e-mail parce que vous ou quelqu'un d'autre a demandé " #~ "un mot de\n" #~ "passe pour votre compte utilisateur. Cependant, nous n'avons aucun\n" #~ "enregistrement d'un utilisateur avec l'e-mail %(email)s dans notre base " #~ "de\n" #~ "données.\n" #~ "\n" #~ "Vous pouvez ignorer en toute sécurité cet e-mail si vous n'avez pas " #~ "demandé de\n" #~ "réinitialisation de mot de passe.\n" #~ "\n" #~ "Si c'était vous, vous pouvez vous inscrire pour un compte en utilisant le " #~ "lien\n" #~ "ci-dessous." #~ msgid "The following email address is associated with your account:" #~ msgstr "Les adresses email suivantes sont associées à votre compte :" #~ msgid "Change Email Address" #~ msgstr "Changer l'adresse e-mail" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "" #~ "Pour garantir la sécurité de votre compte, veuillez entrer votre mot de " #~ "passe:" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Merci d'ouvrir une session avec l'un de vos comptes sociaux. Vous pouvez " #~ "aussi %(link)souvrir un compte%(end_link)s %(site_name)s puis vous " #~ "connecter ci-dessous :" #~ msgid "or" #~ msgstr "ou" #~ msgid "change password" #~ msgstr "modifier le mot de passe" #~ msgid "OpenID Sign In" #~ msgstr "Connexion OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "L'adresse e-mail est déjà associée à un autre compte." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Nous vous avons envoyé un e-mail. Merci de nous contacter si vous ne le " #~ "recevez pas d'ici quelques minutes." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "L'identifiant ou le mot de passe sont incorrects." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Un pseudonyme ne peut contenir que des lettres, des chiffres, ainsi que " #~ "@/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Ce pseudonyme est déjà utilisé, merci d'en choisir un autre." #~ msgid "Shopify Sign In" #~ msgstr "Connexion Shopify" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Vous avez confirmé que l'adresse e-mail de l'utilsateur %(user_display)s " #~ "est %(email)s." #~ msgid "Thanks for using our site!" #~ msgstr "Merci d'utiliser notre site !" django-allauth-65.0.2/allauth/locale/he/000077500000000000000000000000001467545753200200055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/he/LC_MESSAGES/000077500000000000000000000000001467545753200215725ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/he/LC_MESSAGES/django.po000066400000000000000000001522261467545753200234040ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-06-15 10:09+0000\n" "Last-Translator: Eyal Cherevatsky <5116133+eyalch@users.noreply.github.com>\n" "Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Weblate 5.6-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "חשבון זה אינו פעיל כעת." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "לא ניתן להסיר את כתובת האימייל הראשית שלך." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "כתובת אימייל זו כבר משויכת לחשבון זה." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "כתובת האימייל ו/או הסיסמה אינם נכונים." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "משתמש אחר כבר רשום עם כתובת אימייל זו." #: account/adapter.py:62 msgid "Please type your current password." msgstr "אנא הזן את הסיסמה הנוכחית." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "קוד שגוי." #: account/adapter.py:64 msgid "Incorrect password." msgstr "סיסמה שגויה." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "מפתח פגום או פג תוקף." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "אסימון איפוס הסיסמה אינו תקין." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "לא ניתן להוסיף יותר מ-%d כתובות אימייל." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "יותר מדי ניסיונות התחברות כושלים. אנא נסה שוב מאוחר יותר." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "כתובת אימייל זו אינה משויכת לאף חשבון" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "עליך לאמת את כתובת האימייל הראשית שלך." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "לא ניתן להשתמש בשם משתמש זה. אנא בחר שם משתמש אחר." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "שם המשתמש ו/או הסיסמה אינם נכונים." #: account/adapter.py:741 msgid "Use your password" msgstr "להשתמש בסיסמה" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "להשתמש ביישומון אימות" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "מפתח סודי" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "סמן את כתובות האימייל שנבחרו כמאומתות." #: account/apps.py:11 msgid "Accounts" msgstr "חשבונות" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "יש להזין את אותה הסיסמה פעמיים." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "סיסמה" #: account/forms.py:93 msgid "Remember Me" msgstr "זכור אותי" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "כתובת אימייל" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "אימייל" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "שם משתמש" #: account/forms.py:123 msgid "Username or email" msgstr "שם משתמש או אימייל" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "כניסה" #: account/forms.py:137 msgid "Forgot your password?" msgstr "שכחת את סיסמתך?" #: account/forms.py:299 msgid "Email (again)" msgstr "אימייל (שוב)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "אישור כתובת אימייל" #: account/forms.py:311 msgid "Email (optional)" msgstr "אימייל (לא חובה)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "יש להזין את אותו האימייל פעמיים." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "סיסמה (שוב)" #: account/forms.py:554 msgid "Current Password" msgstr "סיסמה נוכחית" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "סיסמה חדשה" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "סיסמה חדשה (שוב)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "קוד" #: account/models.py:26 msgid "user" msgstr "משתמש" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "כתובת אימייל" #: account/models.py:34 msgid "verified" msgstr "מאומת" #: account/models.py:35 msgid "primary" msgstr "ראשי" #: account/models.py:41 msgid "email addresses" msgstr "כתובות אימייל" #: account/models.py:150 msgid "created" msgstr "נוצר" #: account/models.py:151 msgid "sent" msgstr "נשלח" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "מפתח" #: account/models.py:157 msgid "email confirmation" msgstr "אישור באימייל" #: account/models.py:158 msgid "email confirmations" msgstr "אישורים בדואל" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "לא ניתן להוסיף כתובת אימייל לחשבון שמוגן באימות דו-שלבי." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "לא ניתן לבטל אימות דו-שלבי." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "לא ניתן ליצור קודי שחזור מבלי שאימות דו-שלבי יהיה מופעל." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "לא ניתן להפעיל אימות דו-שלבי לפני שאימתת את כתובת האימייל." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "מפתח סודי" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "אימות רב-שלבי" #: mfa/models.py:24 msgid "Recovery codes" msgstr "קודי שחזור" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "מאמת TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "קוד אימות" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "סיסמה" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "קיים כבר חשבון עם כתובת אימייל זו. אנא התחבר לחשבון זה, ואז קשר את חשבון %s " "שלך." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "אסימון פגום." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "לא נבחרה סיסמה לחשבונך." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "לא נמצאו כתובות אימייל מאומתות לחשבונך." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "לא ניתן לנתק את חשבון הצד-השלישי האחרון שנשאר." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "חשבון חברתי זה כבר מקושר למשתמש אחר." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "חשבונות חברתיים" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "ספק" #: socialaccount/models.py:52 msgid "provider ID" msgstr "מזהה ספק" #: socialaccount/models.py:56 msgid "name" msgstr "שם" #: socialaccount/models.py:58 msgid "client id" msgstr "מזהה לקוח" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "מזהה יישום, או מפתח צרכן" #: socialaccount/models.py:63 msgid "secret key" msgstr "מפתח סודי" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "סוד API, סוד לקוח או סוד צרכן" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "מפתח" #: socialaccount/models.py:81 msgid "social application" msgstr "יישום חברתי" #: socialaccount/models.py:82 msgid "social applications" msgstr "יישומים חברתיים" #: socialaccount/models.py:117 msgid "uid" msgstr "מזהה ייחודי" #: socialaccount/models.py:119 msgid "last login" msgstr "התחברות אחרונה" #: socialaccount/models.py:120 msgid "date joined" msgstr "תאריך הצטרפות" #: socialaccount/models.py:121 msgid "extra data" msgstr "מידע נוסף" #: socialaccount/models.py:125 msgid "social account" msgstr "חשבון חברתי" #: socialaccount/models.py:126 msgid "social accounts" msgstr "חשבונות חברתיים" #: socialaccount/models.py:160 msgid "token" msgstr "אסימון" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) או אסימון גישה (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "סוד אסימון" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) או אסימון רענון (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "פג תוקף בתאריך" #: socialaccount/models.py:174 msgid "social application token" msgstr "אסימון יישום חברתי" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "אסימוני יישום חברתי" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "מידע פרופיל שגוי" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "כניסה" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "ביטול" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "אין אסימון בקשה שמור עבור \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "אין אסימון גישה שמור עבור \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "אין גישה למשאב פרטי ב-\"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "חשבון לא פעיל" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "חשבון זה אינו פעיל." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "אימות גישה" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "אנא הזדהה מחדש כדי להגן על חשבונך." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "אפשרויות חלופיות" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "אישור באימייל" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "שלחנו קוד ל-%(email_link)s. הקוד יפוג בקרוב, אז נא להזין אותו בהקדם." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "אמת" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "כניסה" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "הזן קוד כניסה" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "כתובות אימייל" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "כתובות האימייל הבאות משויכות לחשבונך:" #: templates/account/email.html:25 msgid "Verified" msgstr "מאומת" #: templates/account/email.html:29 msgid "Unverified" msgstr "לא מאומת" #: templates/account/email.html:34 msgid "Primary" msgstr "ראשי" #: templates/account/email.html:44 msgid "Make Primary" msgstr "הפוך לראשי" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "שלח אימייל אימות מחדש" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "הסר" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "הוסף כתובת אימייל" #: templates/account/email.html:70 msgid "Add Email" msgstr "הוסף אימייל" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "האם ברצונך להסיר את כתובות האימייל המסומנות?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "החשבון כבר קיים" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "שלום מ%(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "תודה שהשתמשת באתר %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "את/ה מקבל/ת אימייל עקב השינוי הבא שבוצע בחשבונך:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "אם אינך מזהה את השינוי הזה, נא לנקוט מיד באמצעי אבטחה נאותים. השינוי בחשבונך " "מקורו ב:\n" "\n" "- כתובת IP: %(ip)s\n" "- דפדפן: %(user_agent)s\n" "- תאריך: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "האימייל שלך השתנה מ-%(from_email)s ל-%(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "אימייל השתנה" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "האימייל שלך אושר." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "אישור באימייל" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "את/ה מקבל/ת מייל זה מכיוון שהמשתמש %(user_display)s השתמש בכתובת האימייל שלך " "כדי ליצור חשבון ב-%(site_domain)s.\n" "\n" "כדי לאמת זאת, לחץ על הקישור %(activate_url)s." #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "קוד הכניסה שלך מופיע למטה. אנא הזן/י אותו בחלון הדפדפן שפתוח." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "אנא אמת את כתובת האימייל שלך" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "כתובת האימייל %(deleted_email)s הוסרה מחשבונך." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "אימייל הוסר" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "קוד הכניסה שלך מופיע למטה. אנא הזן/י אותו בחלון הדפדפן שפתוח." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "ניתן להתעלם בבטחה ממייל זה אם לא יזמת פעולה זו." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "קוד כניסה" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "סיסמתך שונתה." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "סיסמה שונתה" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "מייל זה נשלח אליך כיוון שאת/ה או מישהו אחר ביקש לאפס את הסיסמה לחשבונך.\n" "במידה ולא ביקשת איפוס סיסמה ניתן להתעלם ממייל זה ללא חשש. לחץ על הקישור מטה " "לאיפוס סיסמתך." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "במידת ושכחת, שם המשתמש שלך הוא %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "מייל איפוס סיסמה" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "סיסמתך אופסה." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "איפוס סיסמה" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "סיסמתך הוגדרה." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "הגדרת סיסמה" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "הודעה זו נשלחה אליך כי את/ה, או מישהו אחר, ניסה לגשת לחשבון עם כתובת האימייל " "%(email)s. עם זאת, אין לנו רישום של חשבון כזה במסד הנתונים שלנו." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "אם זה היית את/ה, תוכל/י להירשם לחשבון באמצעות הקישור למטה." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "חשבון לא ידוע" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "כתובת אימייל" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "כתובת אימייל נוכחית" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "משתנה ל" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "כתובת האימייל שלך עדיין ממתינה לאימות." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "בטל שינוי" #: templates/account/email_change.html:49 msgid "Change to" msgstr "שנה ל" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "שנה אימייל" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "אימות כתובת אימייל" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "אנא אמת ש%(email)s היא כתובת האימייל של " "המשתמש %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "לא ניתן לאשר את %(email)s מכיוון שהיא כבר אושרה על ידי חשבון אחר." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "קישור זה לאימות כתובת אימייל פג תוקף או שאינו תקין. יש להנפיק בקשה חדשה לאימות כתובת אימייל." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "אם לא נרשמת לחשבון בעבר, אנא %(link)sהרשם%(end_link)s תחילה." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "שלחו לי קוד כניסה למייל" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "יציאה" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "האם אתה בטוח שברצונך לצאת?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "לא ניתן להסיר את כתובת האימייל הראשית שלך (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "מייל אימות נשלח ל %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "כתובת האימייל %(email)s אומתה בהצלחה." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "כתובת האימייל %(email)s הוסרה." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "מחובר בהצלחה כ %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "התנתקת מהחשבון." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "קוד כניסה נשלח במייל ל-%(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "הסיסמה שונתה בהצלחה." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "הסיסמה נקבעה בהצלחה." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "כתובת אימייל ראשית הוגדרה." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "החלפת סיסמה" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "שכחת סיסמה?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "שכחת את סיסמתך? הזן את כתובת האימייל שלך כאן, ונשלח לך מייל לאיפוס הסיסמה." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "אפס את הסיסמה" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "אנא צור איתנו קשר אם אתה מתקשה לאפס את הסיסמה." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "שלחנו לך מייל. אם לא קיבלת אותו, בדוק בתיקיית הספאם שלך. אחרת פנה אלינו אם " "לא תקבל אותו תוך מספר דקות." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "אסימון פגום" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "הקישור לאיפוס הסיסמה אינו תקין, כנראה מכיוון שכבר נעשה בו שימוש. לחץ כאן " "לבקשת איפוס סיסמה מחדש." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "סיסמתך שונתה." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "קביעת סיסמה" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "הזינו סיסמה:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "תקבל אימייל המכיל קוד מיוחד לכניסה ללא סיסמה." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "בקש קוד" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "אפשרויות כניסה אחרות" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "הרשמה" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "הרשמה" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "נרשמת בעבר? %(link)sכניסה למערכת%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "הרשמה" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "אפשרויות כניסה אחרות" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "ההרשמה סגורה" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "אנו מצטערים, אך ההרשמה סגורה כעת." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "הערה" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "הנך מחובר כבר כ%(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "אזהרה:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "טרם שייכת כתובת אימייל לחשבונך. מומלץ לשייך כתובת אימייל על מנת לקבל התראות, " "לאפס סיסמה וכו'." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "אשר את כתובת הדואל שלך" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "שלחנו לך אימייל לאימות. עקוב אחר הקישור שסופק כדי לסיים את תהליך ההרשמה. אם " "אינך רואה את דוא\"ל האימות בתיבת הדואר הנכנס הראשית שלך, בדוק את תיקיית " "הספאם. אנא צור איתנו קשר אם לא תקבל את הודעת האימות תוך מספר דקות." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "חלק זה באתר דורש מאיתנו לוודא כי הנך אכן מי שאתה טוען שאתה.\n" "למטרה זו, אנו מבקשים כי תאמת בעלות על כתובת האימייל שלך. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "שלחנו אליך מייל למטרת אימות.\n" "אנא ללץ על הקישור בתוך אימייל זה.\n" "אנא צור עמנו קשר במידה והמייל לא התקבל תוך מספר דקות." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "הערה: אתה עדיין יכול לשנות את " "כתובת האימייל שלך ." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "קישורים לחשבון" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your email has been confirmed." msgid "A security key has been removed." msgstr "האימייל שלך אושר." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "מפתח סודי" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "מפתח סודי" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "האם אתה בטוח שברצונך לצאת?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "מפתח סודי" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "לא מאומת" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "מפתח סודי" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "סיסמה נוכחית" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "נוצר" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "שגיאת התחברות לרשת חברתית" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "אירעה שגיאה במהלך ניסיון התחברות באמצעות חשבון הרשת החברתית שלך." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "ניתן להתחבר לחשבונך באמצעות כל אחד מחשבונות צד שלישי הבאים:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "לא קיימים חשבונות רשת חברתית המקושרים לחשבון זה כרגע." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "הוסף חשבון צד שלישי" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "הוסף חשבון צד שלישי" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "הוסף חשבון צד שלישי" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "התחברות בוטלה" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "ביקשת לבטל את ההתחברות לאתר זה באמצעות אחד מחשבונותיך הקיימים. במידה וטעית, " "אנא המשך להתחברות." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "החשבון החברתי קושר בהצלחה." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "חשבון חברתי זה נותק." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "אתה עומד להשתמש בחשבון %(provider_name)s שלך כדי\n" "להתחבר ל%(site_name)s. לסיום, אנא מלא את הטופס הבא:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "כתובות אימייל" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "סיסמה נוכחית" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "קישורים לחשבון" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "הסיסמה חייבת להיות באורך של לפחות {0} תווים." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "שלום מ%(site_name)s!\n" #~ "\n" #~ "מייל זה נשלח אליך כיוון שאתה או מישהו אחר ביקש סיסמה עבור חשבונך ב " #~ "%(site_name)s.\n" #~ "במידה ולא ביקשת איפוס סיסמה ניתן להתעלם ממייל זה ללא חשש. לחץ על הקישור " #~ "מטה לאיפוס סיסמתך." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "כתובות האימייל הבאות משויכות לחשבונך:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "אימות כתובת אימייל" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "אנא הכנס עם אחד מהחשבונות הקיימים שלך.\n" #~ "או, %(link)sהרשם%(end_link)s לחשבון %(site_name)s והתחבר:" #~ msgid "or" #~ msgstr "או" #~ msgid "change password" #~ msgstr "החלפת סיסמה" #~ msgid "OpenID Sign In" #~ msgstr "כניסה באמצעות OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "כתובת אימייל זו כבר משויכת לחשבון אחר." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "המייל נשלח. אנא צור איתנו קשר אם הוא אינו מתקבל תוך מספר דקות." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "שם המשתמש ו/או הסיסמא אינם נכונים" #~ msgid "This username is already taken. Please choose another." #~ msgstr "שם משתמש זה כבר תפוס, אנא ציין שם אחר" #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "כניסה" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "אישרת בהצלחה כי %(email)s הנה כתובת דואר " #~ "אלקטרוני עבור המשתמש %(user_display)s." #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "דואל אישור נשלח אל %(email)s" #~ msgid "Delete Password" #~ msgstr "מחיקת סיסמא" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "אתה רשאי למחוק את סיסמאתך כיוון שהנך מחובר באמצעות OpenID" #~ msgid "delete my password" #~ msgstr "מחק סיסמא" #~ msgid "Password Deleted" #~ msgstr "הסיסמא נמחקה" django-allauth-65.0.2/allauth/locale/hr/000077500000000000000000000000001467545753200200225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/hr/LC_MESSAGES/000077500000000000000000000000001467545753200216075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/hr/LC_MESSAGES/django.po000066400000000000000000001467661467545753200234350ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Bojan Mihelac , 2013-05-22 # Mislav Cimperšak . 2013-07-09 # Goran Cetušić . 2015-11-27 # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:48+0200\n" "Last-Translator: \n" "Language-Team: Bojan Mihelac \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Poedit 1.5.4\n" "X-Translated-Using: django-rosetta 0.7.2\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Ovaj korisnički račun je privremeno neaktivan." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Nije moguće ukloniti vašu primarnu e-mail adresu %(email)s " #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "E-mail adresa je već registrirana s ovim korisničkim računom." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "E-mail adresa i/ili lozinka nisu ispravni." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Već postoji korisnik registriran s ovom e-mail adresom." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Molimo unesite trenutnu lozinku." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Trenutna lozinka" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Neispravan token" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "" #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Vaš korisnički račun nema potvrđenu e-mail adresu." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Upisana e-mail adresa nije dodijeljena niti jednom korisničkom računu" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Vaša primarna adresa more biti potvrđena." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Nije moguće koristiti upisano korisničko ime. Molimo odaberite drugo." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Korisničko ime i/ili lozinka nisu ispravni." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Zaboravili ste lozinku?" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Vaša primarna adresa more biti potvrđena." #: account/apps.py:11 msgid "Accounts" msgstr "Korisnički računi" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Potrebno je upisati istu lozinku svaki put." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Lozinka" #: account/forms.py:93 msgid "Remember Me" msgstr "Zapamti me" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-mail adresa" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Korisničko ime" #: account/forms.py:123 msgid "Username or email" msgstr "Korisničko ime ili e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Prijava" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Zaboravili ste lozinku?" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "E-mail (neobavezno)" #: account/forms.py:303 #, fuzzy #| msgid "email confirmation" msgid "Email address confirmation" msgstr "E-mail potvrda" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (neobavezno)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Potrebno je upisati istu lozinku svaki put." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Lozinka (ponovno)" #: account/forms.py:554 msgid "Current Password" msgstr "Trenutna lozinka" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nova lozinka" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nova lozinka (ponovno)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "korisnik" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-mail adresa" #: account/models.py:34 msgid "verified" msgstr "potvrđena" #: account/models.py:35 msgid "primary" msgstr "primarna" #: account/models.py:41 msgid "email addresses" msgstr "E-mail adrese" #: account/models.py:150 msgid "created" msgstr "" #: account/models.py:151 msgid "sent" msgstr "" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "" #: account/models.py:157 msgid "email confirmation" msgstr "E-mail potvrda" #: account/models.py:158 msgid "email confirmations" msgstr "E-mail potvrde" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 msgid "Master key" msgstr "" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Lozinka" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Korisnički račun s ovom e-mail adresom već postoji. Molimo da se prvo " "ulogirate pod tim korisničkim računom i spojite svoj %s račun" #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Neispravan token" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Vaš korisnički račun nema postavljenu lozinku." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Vaš korisnički račun nema potvrđenu e-mail adresu." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Možete se prijaviti u vaš korisnički račun koristeći jedan od sljedećih " "povezanih računa:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Korisnički račun društvene mreže je već povezan s drugim računom." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Korisnički računi" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "" #: socialaccount/models.py:52 msgid "provider ID" msgstr "" #: socialaccount/models.py:56 msgid "name" msgstr "naziv" #: socialaccount/models.py:58 msgid "client id" msgstr "" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "" #: socialaccount/models.py:63 msgid "secret key" msgstr "" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "" #: socialaccount/models.py:81 msgid "social application" msgstr "" #: socialaccount/models.py:82 msgid "social applications" msgstr "" #: socialaccount/models.py:117 msgid "uid" msgstr "" #: socialaccount/models.py:119 msgid "last login" msgstr "" #: socialaccount/models.py:120 msgid "date joined" msgstr "" #: socialaccount/models.py:121 msgid "extra data" msgstr "" #: socialaccount/models.py:125 msgid "social account" msgstr "" #: socialaccount/models.py:126 msgid "social accounts" msgstr "" #: socialaccount/models.py:160 msgid "token" msgstr "" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "" #: socialaccount/models.py:174 msgid "social application token" msgstr "" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Prijava" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Neispravan odaziv pri dohvatu tokena zahtjeva od \\\"%s\\\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Neispravan odaziv pri dohvatu pristupnog tokena od \\\"%s\\\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Ne postoji pohranjeni token za \\\"%s\\\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Token za pristup za \\\"%s\\\" nije pohranjen." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Nemate pristup zaštičenim sadržajima na \\\"%s\\\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Neispravan odaziv pri dohvatu tokena zahtjeva od \\\"%s\\\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Račun je neaktivan" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Ovaj korisnički račun je neaktivan." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Potvrdite vašu e-mail adresu" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "E-mail potvrda" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Potvrda" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Prijava" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-mail adrese" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Slijedeće e-mail adrese su povezane sa vašim korisničkim računom" #: templates/account/email.html:25 msgid "Verified" msgstr "Potvrđena" #: templates/account/email.html:29 msgid "Unverified" msgstr "Nepotvrđena" #: templates/account/email.html:34 msgid "Primary" msgstr "Primarna" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Označi kao primarnu" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Ponovno pošalji e-mail za potvrdu" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Ukloni" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Dodaj e-mail adresu" #: templates/account/email.html:70 msgid "Add Email" msgstr "Dodaj e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Da li zaista želite ukloniti e-mail adresu?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "E-mail adresa" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Potvrdili ste e-mail adresu %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "E-mail potvrda" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s at " #| "%(site_domain)s has given yours as an e-mail address to connect their " #| "account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Pozdravi od %(site_name)s!\n" "\n" "Primili ste ovaj e-mail jer je korisnik %(user_display)s na stranici " "%(site_domain)s upisao ovu e-mail adresu kao svoju.\n" "\n" "Za potvrdu, kliknite %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Potvrdite vašu e-mail adresu" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Ukloni" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Prijava" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Lozinka je uspješno promjenjena." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Lozinka (ponovno)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account at %(site_domain)s.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Pozdravi od %(site_name)s!\n" "\n" "Primili ste ovaj e-mail jer ste vi ili netko drugi zatražili lozinku za vaš " "korisnički račun na %(site_domain)s.\n" "Ako niste zatražili resetiranje lozinke, slobodno zanemarite ovaj e-mail. " "Kliknite na sljedeći link za resetiranje lozinke." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Za slučaj da ste zaboravili, vaše korisničko ime je %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail za resetiranje lozinke" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Lozinka je uspješno promjenjena." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Resetiranje lozinke" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Lozinka je uspješno promjenjena." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Resetiranje lozinke" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Korisnički račun" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "E-mail adrese" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Trenutna lozinka" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Vaša primarna adresa more biti potvrđena." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Potvrdite vašu e-mail adresu" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Molimo potvrdite da %(email)s je e-mail " "adresa za korisnika %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Korisnički račun društvene mreže je već povezan s drugim računom." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Ovaj link za potvrdu je istekao ili je neispravan. Zatražite novi e-mail za potvrdu." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ukoliko još niste napravili korisnički račun, prvo se " "%(link)sregistrirajte%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Odjava" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Jeste li sigurni da se želite odjaviti?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Nije moguće ukloniti vašu primarnu e-mail adresu %(email)s " #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "E-mail s linkom za potvrdu registracije je poslan na %(email)s" #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Potvrdili ste e-mail adresu %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Uklonjena e-mail adresa %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Uspješno ste prijavljeni kao %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Uspješno ste se odjavili." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Lozinka je uspješno promijenjena." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Lozinka je uspješno postavljena." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primarna e-mail adresa je postavljena" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Promjena lozinke" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Zaboravili ste lozinku?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Zaboravili ste lozinku? Unesite vašu e-mail adresu i poslati ćemo vam e-mail " "uz pomoć kojeg ćete promijeniti lozinku." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Resetiraj moju lozinku" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Molimo konktaktirajte nas ukoliko imate problema pri promjeni lozinke." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Poslali smo e-mail na vašu adresu u svrhu potvrde. Molimo kliknite na link " "unutar e-maila.\n" "Molimo kontaktirajte nas ako ga ne primite unutar nekoliko sljedećih minuta." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Neispravan token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Link za poništavanje lozinke je nevažeći, vjerojatno jer je već bio " "korišten. Molimo vas ponovite zahtjev za " "resetiranje lozinke." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Lozinka je uspješno promjenjena." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Postavljanje lozinke" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Zaboravili ste lozinku?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registracija" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registracija" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Već imate korisnički račun? %(link)sPrijavite se%(end_link)s!" #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Registracija" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Prijave zatvorene" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Na žalost, registracija je privremeno nedostupna." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Napomena" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "već ste prijavljeni kao %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Pažnja:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Trenutno nemate postavljenu niti jednu e-mail adresu. Postavite e-mail " "adresu kako biste mogli primati obavijesti, promijeniti lozinku i slično." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Potvrdite vašu e-mail adresu" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Poslali smo e-mail u svrhu potvrde. Sljedite dani link za završetak postupka " "registracije. Molimo kontaktirajte nas ukoliko ga ne primite unutar " "sljedećih nekoliko minuta." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Ovaj dio web stranice zahtjeva da potvrdite da jeste tko tvrdite da jeste. " "Zbog toga je nužno da potvrdite da ste vi vlasnik dane e-mail adrese." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Poslali smo e-mail na vašu adresu u svrhu potvrde. Molimo kliknite na link " "unutar e-maila.\n" "Molimo kontaktirajte nas ako ga ne primite unutar nekoliko sljedećih minuta." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Napomena: još uvijek možete izmijeniti vašu e-mail adresu." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Povezani računi" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Potvrdili ste e-mail adresu %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Jeste li sigurni da se želite odjaviti?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Nepotvrđena" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Trenutna lozinka" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Greška pri prijavi s računom društvene mreže" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Došlo je do greške pri prijavi s vašim računom društvene mreže." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Možete se prijaviti u vaš korisnički račun koristeći jedan od sljedećih " "povezanih računa:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Trenutno nemate niti jedan račun s društvenih mreža povezan s trenutnim " "korisničkim računom." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Dodaj račun društvenih mreža." #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Dodaj račun društvenih mreža." #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Dodaj račun društvenih mreža." #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Prijava otkazana" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Odlučili ste da se ne želite prijaviti na našu stranicu koristeći jedan od " "vaših postojećih računa s društvenih mreža. Ako je to bila greška, molimo " "kliknite i prijavite se." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Račun društvene mreže je povezan" #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Račun društvene mreže je isključen" #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Odabrali ste da ćete koristiti vaš %(provider_name)s račun za prijavu u " "stranicu %(site_name)s. Kao posljednji korak, molimo vas ispunite sljedeći " "obrazac:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "E-mail adrese" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Trenutna lozinka" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Povezani računi" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Lozinka treba imati najmanje {0} znakova." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Pozdravi od %(site_name)s!\n" #~ "\n" #~ "Primili ste ovaj e-mail jer ste vi ili netko drugi zatražili lozinku za " #~ "vaš korisnički račun na %(site_domain)s.\n" #~ "Ako niste zatražili resetiranje lozinke, slobodno zanemarite ovaj e-mail. " #~ "Kliknite na sljedeći link za resetiranje lozinke." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Slijedeće e-mail adrese su povezane sa vašim korisničkim računom" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Potvrdite vašu e-mail adresu" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Molimo prijavite se s jednim od vaših postojećih računa društvenih mreža " #~ "ili se %(link)sregistrirajte%(end_link)s za korisnički račun na " #~ "%(site_name)s i prijavite se." #~ msgid "or" #~ msgstr "ili" #~ msgid "change password" #~ msgstr "promjena lozinke" #~ msgid "OpenID Sign In" #~ msgstr "Prijava s OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "E-mail adresa je već registrirana s drugim korisničkim računom." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Poslali smo vam e-mail. Molimo kontaktirajte nas ako ga ne primite unutar " #~ "nekoliko sljedećih minuta." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Korisničko ime i/ili zaporka nisu ispravni." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "Korisničko ime može sadržavati samo slova, brojeve i @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "" #~ "Korisničko ime je već zauzeto. Molimo izaberite drugo korisničko ime." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Prijava" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Potvrdili ste da je %(email)s e-mail " #~ "adresa za korisnika %(user_display)s." django-allauth-65.0.2/allauth/locale/hu/000077500000000000000000000000001467545753200200255ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/hu/LC_MESSAGES/000077500000000000000000000000001467545753200216125ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/hu/LC_MESSAGES/django.po000066400000000000000000001445531467545753200234300ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:45+0200\n" "Last-Translator: Tamás Makó \n" "Language-Team: \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.7.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "A felhasználó jelenleg nem aktív." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Az elsődleges email cím (%(email)s) nem törölhető." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Ez az email cím már hozzá van rendelve ehhez a felhasználóhoz." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "A megadott email vagy a jelszó hibás." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Egy felhasználó már regisztrált ezzel az email címmel." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Kérlek add meg az aktuális jelszavadat!" #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Jelenlegi jelszó" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Hibás token" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "" #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "A felhasználódnak nincs ellenőrzött email címe." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Az email cím nincs hozzárendelve egyetlen felhasználóhoz sem" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Az elsődleges email címet ellenőriznunk kell." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Ez a felhasználói azonosító nem használható. Kérlek válassz másikat!" #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "A megadott felhasználó vagy a jelszó hibás." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Elfelejtett jelszó?" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Az elsődleges email címet ellenőriznunk kell." #: account/apps.py:11 msgid "Accounts" msgstr "Felhasználók" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Ugyanazt a jelszót kell megadni mindannyiszor." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Jelszó" #: account/forms.py:93 msgid "Remember Me" msgstr "Emlékezz rám" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Email" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Email" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Felhasználó azonosító" #: account/forms.py:123 msgid "Username or email" msgstr "Felhasználó azonosító vagy email" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Bejelentkezés" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Elfelejtett jelszó?" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "Email (nem kötelező)" #: account/forms.py:303 #, fuzzy #| msgid "Email address" msgid "Email address confirmation" msgstr "Email" #: account/forms.py:311 msgid "Email (optional)" msgstr "Email (nem kötelező)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Ugyanazt a jelszót kell megadni mindannyiszor." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Jelszó (ismét)" #: account/forms.py:554 msgid "Current Password" msgstr "Jelenlegi jelszó" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Új jelszó" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Új jelszó (ismét)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "" #: account/models.py:34 msgid "verified" msgstr "" #: account/models.py:35 msgid "primary" msgstr "" #: account/models.py:41 msgid "email addresses" msgstr "" #: account/models.py:150 msgid "created" msgstr "" #: account/models.py:151 msgid "sent" msgstr "" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "" #: account/models.py:157 msgid "email confirmation" msgstr "" #: account/models.py:158 msgid "email confirmations" msgstr "" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 msgid "Master key" msgstr "" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Jelszó" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Ezzel az email címmel már létezik egy felhasználó . Először jelentkezz be, " "majd kapcsold össze a(z) %s felhasználóval." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Hibás token" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "A felhasználódnak nincs beállított jelszava." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "A felhasználódnak nincs ellenőrzött email címe." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "Az alábbi felhasználói fiókok bármelyikét használhatod belépéshez:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "A közösségi felhasználó már egy másik felhasználóhoz tartozik." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Közösségi Felhasználók" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "" #: socialaccount/models.py:52 msgid "provider ID" msgstr "" #: socialaccount/models.py:56 msgid "name" msgstr "" #: socialaccount/models.py:58 msgid "client id" msgstr "" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "" #: socialaccount/models.py:63 msgid "secret key" msgstr "" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "" #: socialaccount/models.py:81 msgid "social application" msgstr "" #: socialaccount/models.py:82 msgid "social applications" msgstr "" #: socialaccount/models.py:117 msgid "uid" msgstr "" #: socialaccount/models.py:119 msgid "last login" msgstr "" #: socialaccount/models.py:120 msgid "date joined" msgstr "" #: socialaccount/models.py:121 msgid "extra data" msgstr "" #: socialaccount/models.py:125 msgid "social account" msgstr "" #: socialaccount/models.py:126 msgid "social accounts" msgstr "" #: socialaccount/models.py:160 msgid "token" msgstr "" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "" #: socialaccount/models.py:174 msgid "social application token" msgstr "" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Bejelentkezés" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "" #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Felhasználó nem aktív" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "A felhasználó nem aktív." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Email cím megerősítése" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email address" msgid "Email Verification" msgstr "Email" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Megerősítés" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Belépés" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Email címek" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "A következő email címek tartoznak a felhasználódhoz:" #: templates/account/email.html:25 msgid "Verified" msgstr "Ellenőrzött" #: templates/account/email.html:29 msgid "Unverified" msgstr "Nem ellenőrzött" #: templates/account/email.html:34 msgid "Primary" msgstr "Elsődleges" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Legyen elsődleges" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Ellenőrzés újraküldése" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Töröl" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Új email cím" #: templates/account/email.html:70 msgid "Add Email" msgstr "Új email" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Tényleg törölni akarod a kijelölt email címet?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Email" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "A(z) %(email)s cím visszaigazolása megtörtént." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Confirmation" msgstr "Email" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "User %(user_display)s at %(site_name)s has given this as an email " #| "address.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "A(z) %(user_display)s felhasználó a(z) %(site_name)s oldalon ezt az email " "címet adta meg.\n" "\n" "Megerősítéshez látogasd meg ezt az oldalt %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 #, fuzzy #| msgid "Confirm Email Address" msgid "Please Confirm Your Email Address" msgstr "Email cím megerősítése" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Töröl" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Belépés" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "A jelszavad megváltozott." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Jelszó (ismét)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account at %(site_domain)s.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Azért kaptad ezt a levelet, mert te vagy valaki más jelszócserét kért a(z) " "%(site_domain)s oldalon.\n" "Nyugodtan hagyd levelünket figyelmen kívül, ha nem te kérted. A jelszó " "cseréjéhez kövesd az alábbi linket." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Ha esetleg nem emlékeznél pontosan, a felhasználód %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Jelszó csere email" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "A jelszavad megváltozott." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Új jelszó kérése" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "A jelszavad megváltozott." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Új jelszó kérése" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Felhasználó" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Email címek" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Jelenlegi jelszó" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Az elsődleges email címet ellenőriznunk kell." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Email" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Email" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Email cím megerősítése" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Kérlek erősítsd meg, hogy a(z) %(email)s " "email a(z) %(user_display)s felhasználóhoz tartozik." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "A közösségi felhasználó már egy másik felhasználóhoz tartozik." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Az email visszaigazolás címe már lejárt vagy érvénytelen. Itt kérhetsz újat.\"" #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ha még nem rendelkezel felhasználóval, akkor először " "%(link)sregisztrálnod%(end_link)s kell." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Kilépés" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Biztosan kijelentkezel?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Az elsődleges email cím (%(email)s) nem törölhető." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Megerősítő levelet küldtünk a(z) %(email)s címre." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "A(z) %(email)s cím visszaigazolása megtörtént." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s email cím törölve." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Sikeres bejelentkezés, mint %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Sikeresen kijelentkezés." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Jelszó sikeresen megváltoztatva." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Jelszó sikeresen beállítva." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Elsődleges email cím beállítva." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Jelszócsere" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Elfelejtett jelszó?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Elfelejtetted a jelszavadat? Add meg az email címedet és küldünk egy linket, " "ahol újat kérhetsz." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Új jelszó kérése" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Kérlek vedd fel velünk a kapcsolatot, ha problémád adódik a jelszó " "beállításával." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Elküldtük az ellenőrző emailt.\n" "Az ellenőrzéshez kövesd a benne található címet! Kérlek vedd fel \n" "velünk a kapcsolatot, ha az email nem érkezik meg perceken belül!" #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Hibás token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Az új jelszó kérő cím érvénytelen vagy már felhasználták. Itt tudsz újat kérni." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "A jelszavad megváltozott." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Jelszó beállítása" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Elfelejtett jelszó?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Regisztráció" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Regisztráció" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Van már felhasználód? Akkor %(link)sitt jelentkezz be%(end_link)s!" #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Regisztráció" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Regisztráció lezárva" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Sajnáljuk, de jelenleg nem lehet regisztrálni." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Megjegyzés" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "Már bejelentkeztél, mint %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Figyelem:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Jelenleg nincs egyetlen email címed sem beállítva. Nagyon fontos lenne, " "hiszen csak így kaphatsz értesítéseket és így tudod a jelszavadat " "megváltoztatni." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Ellenőrizd az emailedet" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Elküldtük az ellenőrző emailt. A regisztráció befejezéséhez kövesd a benne " "található linket! Kérlek vedd fel velünk a kapcsolatot, ha az email nem " "érkezik meg perceken belül!" #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Az oldal ezen része megköveteli, hogy ellenőrizzük\n" "a felhasználó azonosságát. Ezért most arra kérünk, \n" "hogy ellenőrizd a hozzáférésedet az email címedhez. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Elküldtük az ellenőrző emailt.\n" "Az ellenőrzéshez kövesd a benne található címet! Kérlek vedd fel \n" "velünk a kapcsolatot, ha az email nem érkezik meg perceken belül!" #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Megjegyzés: az email címet még mindig meg tudod változtatni." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Egyéb felhasználói fiókok" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "A(z) %(email)s cím visszaigazolása megtörtént." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Biztosan kijelentkezel?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Nem ellenőrzött" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Jelenlegi jelszó" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Közösségi hálózat bejelentkezési hiba" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Hiba történt, miközben megpróbáltunk bejelentkezni a közösségi " "felhasználóddal." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Az alábbi felhasználói fiókok bármelyikét használhatod belépéshez:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Jelenleg nincs közösségi felhasználó a fiókodhoz rendelve." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Új közösségi felhasználó hozzáadása" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Új közösségi felhasználó hozzáadása" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Új közösségi felhasználó hozzáadása" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Bejelentkezés leállítva" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Ha a bejelntkezési folyamatot véletlenül állítottad le, itt újra megpróbálhatod." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "A közösségi felhasználó hozzárendelve." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "A közösségi felhasználó kapcsolat törölve." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "A(z) %(provider_name)s felhasználódat használod a (z) %(site_name)s " "bejelentkezés\n" "Utolsó lépésként kérlek töltsd ki az alábbi adatlapot:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Email címek" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Jelenlegi jelszó" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Egyéb felhasználói fiókok" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "A jelszónak minimum {0} hosszúnak kell lennnie." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Azért kaptad ezt a levelet, mert te vagy valaki más jelszócserét kért " #~ "a(z) %(site_domain)s oldalon.\n" #~ "Nyugodtan hagyd levelünket figyelmen kívül, ha nem te kérted. A jelszó " #~ "cseréjéhez kövesd az alábbi linket." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "A következő email címek tartoznak a felhasználódhoz:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Email cím megerősítése" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Kérlek jelentkezz be\n" #~ "az egyik felhasználóddal vagy %(link)sregisztrálj%(end_link)s\n" #~ "új %(site_name)s felhasználót és használd azt:" #~ msgid "or" #~ msgstr "vagy" #~ msgid "OpenID Sign In" #~ msgstr "OpenID bejelentkezés" #~ msgid "This email address is already associated with another account." #~ msgstr "Ez az email cím már hozzá van rendelve egy másik felhasználóhoz." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Elküldtük az emailt. Kérlek vedd fel velünk a kapcsolatot, ha nem kapod " #~ "meg perceken belül." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "A megadott bejelentkezési azonosító vagy a jelszó hibás." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "A felhasználói azonosítók csak betűket, számokat és a @/./+/-/_ " #~ "karaktereket tartalmazhatnak." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Ez a felhasználói azonosító már foglalt. Kérlek válassz másikat!" #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Belépés" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Sikeresen visszaigazolás. A(z) %(email)s " #~ "email a(z) %(user_display)s felhasználóhoz tartozik." #~ msgid "Thanks for using our site!" #~ msgstr "Köszönjük, hogy az oldalunkat használja!" django-allauth-65.0.2/allauth/locale/id/000077500000000000000000000000001467545753200200055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/id/LC_MESSAGES/000077500000000000000000000000001467545753200215725ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/id/LC_MESSAGES/django.po000066400000000000000000001452441467545753200234060ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-13 16:21+0000\n" "Last-Translator: Reza Almanda \n" "Language-Team: Indonesian \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Akun ini sedang tidak aktif." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Anda tidak dapat menghapus alamat email utama Anda." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Alamat e-mail ini sudah terhubung dengan akun ini." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Alamat e-mail dan/atau kata sandi yang anda masukkan tidak benar." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Seorang pengguna sudah terdaftar dengan alamat e-mail ini." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Silahkan ketik kata sandi Anda saat ini." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Kode salah." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Kata sandi salah." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Kunci tidak valid atau kedaluwarsa." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Token untuk mengatur ulang kata sandi tidak valid." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Anda tidak dapat menambahkan lebih dari %d alamat e-mail." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Terlalu banyak percobaan masuk yang gagal. Coba lagi nanti." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Alamat e-mail ini tidak terhubung dengan akun pengguna mana pun" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Alamat e-mail utama Anda harus diverifikasi." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Name pengguna tidak dapat digunakan. Silahkan gunakan nama pengguna lain." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Nama pengguna dan/atau kata sandi yang anda masukkan tidak benar." #: account/adapter.py:741 msgid "Use your password" msgstr "Gunakan kata sandi Anda" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Gunakan aplikasi atau kode autentikator" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Gunakan kunci keamanan" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Tandai alamat email yang dipilih sebagai terverifikasi" #: account/apps.py:11 msgid "Accounts" msgstr "Akun" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Anda harus mengetikkan kata sandi yang sama setiap kali." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Kata sandi" #: account/forms.py:93 msgid "Remember Me" msgstr "Ingat Saya" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Alamat e-mail" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nama pengguna" #: account/forms.py:123 msgid "Username or email" msgstr "Nama pengguna atau e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Masuk" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Lupa kata sandi Anda?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (lagi)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Konfirmasi alamat e-mail" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (opsional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Anda harus mengetikkan e-mail yang sama setiap kali." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Kata sandi (lagi)" #: account/forms.py:554 msgid "Current Password" msgstr "Kata sandi saat ini" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Kata sandi baru" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Kata sandi baru (lagi)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kode" #: account/models.py:26 msgid "user" msgstr "pengguna" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "alamat e-mail" #: account/models.py:34 msgid "verified" msgstr "terverifikasi" #: account/models.py:35 msgid "primary" msgstr "utama" #: account/models.py:41 msgid "email addresses" msgstr "alamat e-mail" #: account/models.py:150 msgid "created" msgstr "dibuat" #: account/models.py:151 msgid "sent" msgstr "dikirim" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "kunci" #: account/models.py:157 msgid "email confirmation" msgstr "konfirmasi e-mail" #: account/models.py:158 msgid "email confirmations" msgstr "konfirmasi e-mail" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Anda tidak dapat menambahkan alamat email ke akun yang dilindungi oleh " "autentikasi dua faktor." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Anda tidak dapat menonaktifkan autentikasi dua faktor." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Anda tidak dapat membuat kode pemulihan tanpa mengaktifkan autentikasi dua " "faktor." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Anda tidak dapat mengaktifkan autentikasi dua faktor hingga Anda " "memverifikasi alamat email Anda." #: mfa/adapter.py:141 msgid "Master key" msgstr "Kunci utama" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Kunci cadangan" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Kunci no. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Kode pemulihan" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Otentikator TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Kode autentikator" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Tanpa kata sandi" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Mengaktifkan operasi tanpa kata sandi memungkinkan Anda untuk masuk hanya " "dengan menggunakan kunci ini, tetapi memberlakukan persyaratan tambahan " "seperti perlindungan biometrik atau PIN." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Akun sudah ada dengan alamat email ini. Silakan masuk ke akun tersebut " "terlebih dahulu, lalu hubungkan akun %s Anda." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Token Salah." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Akun Anda tidak memiliki kata sandi." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Akun Anda tidak memiliki alamat e-mail yang terverifikasi." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Anda tidak dapat memutuskan akun pihak ketiga Anda yang terakhir." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Akun pihak ketiga sudah terhubung ke akun yang berbeda." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Akun Sosial" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "pemberi" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID penyedia" #: socialaccount/models.py:56 msgid "name" msgstr "nama" #: socialaccount/models.py:58 msgid "client id" msgstr "id klien" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID Aplikasi, atau kunci konsumen" #: socialaccount/models.py:63 msgid "secret key" msgstr "kunci rahasia" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Kunci API, kunci klien, atau kunci konsumen" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Kunci" #: socialaccount/models.py:81 msgid "social application" msgstr "aplikasi sosial" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplikasi sosial" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "masuk terakhir" #: socialaccount/models.py:120 msgid "date joined" msgstr "tanggal bergabung" #: socialaccount/models.py:121 msgid "extra data" msgstr "data tambahan" #: socialaccount/models.py:125 msgid "social account" msgstr "akun sosial" #: socialaccount/models.py:126 msgid "social accounts" msgstr "akun sosial" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) atau token akses (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "rahasia token" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) atau token refresh (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "kadaluarsa pada" #: socialaccount/models.py:174 msgid "social application token" msgstr "token aplikasi sosial" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "token-token aplikasi sosial" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Data profil tidak valid" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Masuk" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Respon tidak valid saat meminta token request dari \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Respon tidak valid saat meminta token akses dari \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Tidak ada token request yang disimpan untuk \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Tidak ada token akses yang disimpan untuk \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Tidak ada akses ke sumber daya pribadi pada \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Respon tidak valid saat meminta token request dari \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Akun Tidak Aktif" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Akun ini tidak aktif." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Konfirmasi Alamat E-mail" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "konfirmasi e-mail" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "rahasia token" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Konfirmasi" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Masuk" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Alamat E-mail" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Alamat-alamat e-mail berikut ini terkait dengan akun Anda:" #: templates/account/email.html:25 msgid "Verified" msgstr "Terverifikasi" #: templates/account/email.html:29 msgid "Unverified" msgstr "Tidak Terverifikasi" #: templates/account/email.html:34 msgid "Primary" msgstr "Utama" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Jadikan Utama" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Kirim Ulang Verifikasi" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Hapus" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Tambahkan Alamat E-mail" #: templates/account/email.html:70 msgid "Add Email" msgstr "Tambahkan E-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Apakah Anda benar-benar ingin menghapus alamat e-mail yang dipilih?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Halo dari %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Terima kasih telah menggunakan %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Alamat e-mail" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Anda telah mengkonfirmasi %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "konfirmasi e-mail" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Anda menerima e-mail ini karena pengguna %(user_display)s telah memberikan " "alamat e-mail Anda untuk mendaftarkan akun di %(site_domain)s.\n" "\n" "Untuk mengkonfirmasi bahwa ini benar, kunjungi %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Mohon Konfirmasi Alamat E-mail Anda" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Hapus" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Masuk" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Kata sandi Anda telah diubah." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Kata sandi (lagi)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Anda menerima e-mail ini karena Anda atau orang lain telah meminta kata " "sandi untuk akun Anda.\n" "Abaikan jika Anda tidak meminta reset kata sandi. Klik link di bawah untuk " "mereset kata sandi Anda." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Jikalau Anda lupa, nama pengguna Anda adalah %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail Reset Kata Sandi" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Kata sandi Anda telah diubah." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Reset Kata Sandi" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Kata sandi Anda telah diubah." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Reset Kata Sandi" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "Akun" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Alamat E-mail" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Kata sandi saat ini" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Alamat e-mail utama Anda harus diverifikasi." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Konfirmasi Alamat E-mail" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Mohon konfirmasi bahwa %(email)s adalah " "alamat e-mail untuk pengguna %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Akun sosial sudah terhubung ke akun lain." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Link konfirmasi e-mail ini sudah kadaluwarsa atau tidak valid. Mohon mengirimkan permintaan konfirmasi e-mail baru." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Jika Anda belum membuat akun, mohon %(link)sdaftar%(end_link)s terlebih " "dahulu." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Keluar" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Anda yakin ingin keluar?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Anda tidak dapat menghapus alamat e-mail utama Anda (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "E-mail konfirmasi dikirim ke %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Anda telah mengkonfirmasi %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Alamat e-mail %(email)s telah dihapus." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Berhasil masuk sebagai %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Anda telah keluar." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Kata sandi berhasil diubah." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Kata sandi berhasil setel." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Alamat e-mail utama telah disetel." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Ubah Kata Sandi" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Lupa Kata Sandi?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Lupa kata sandi Anda? Masukkan alamat e-mail Anda di bawah, dan kami akan " "mengirimkan e-mail yang membolehkan Anda untuk mengubahnya." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Reset Kata Sandi Saya" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Mohon hubungi kami jika Anda mengalami masalah saat mengubah kata sandi Anda." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Kami telah mengirimkan e-mail kepada Anda untuk\n" "verifikasi. Silakan klik tautan didalam e-mail ini. Silakan\n" "hubungi kami jika Anda tidak menerimanya dalam beberapa menit." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Token Salah" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Link reset kata sandi tidak valid, mungkin karena telah digunakan. Silakan " "minta reset kata sandi baru." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Kata sandi Anda telah diubah." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Setel Kata Sandi" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Lupa Kata Sandi?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Daftar" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Daftar" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Sudah memiliki akun? Silakan %(link)smasuk%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Daftar" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Daftar Ditutup" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Mohon maaf, tapi pendaftaran saat ini ditutup." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Catatan" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "Anda sudah masuk sebagai %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Peringatan:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Anda saat ini tidak memiliki alamat e-mail yang disetel. Anda seharusnya " "menambahkan alamat e-mail untuk menerima notifikasi, mereset kata sandi, dll." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifikasi Alamat E-mail Anda" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Kami telah mengirimkan e-mail kepada Anda untuk verifikasi. Ikuti tautan " "yang disediakan untuk menyelesaikan proses pendaftaran. Silahkan hubungi " "kami jika Anda tidak menerimanya dalam beberapa menit." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Bagian dari situs ini mengharuskan kami untuk memverifikasi bahwa\n" "Anda adalah apa yang Anda klaim. Untuk tujuan ini, kami mengharuskan Anda\n" "memverifikasi kepemilikan alamat e-mail Anda. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Kami telah mengirimkan e-mail kepada Anda untuk\n" "verifikasi. Silakan klik tautan didalam e-mail ini. Silakan\n" "hubungi kami jika Anda tidak menerimanya dalam beberapa menit." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Catatan: Anda masih bisa mengganti alamat e-mail Anda." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Koneksi Akun" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "rahasia token" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "rahasia token" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Anda telah mengkonfirmasi %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "rahasia token" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "rahasia token" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "kunci rahasia" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "kunci rahasia" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Anda yakin ingin keluar?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "kunci rahasia" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Tidak Terverifikasi" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "kunci rahasia" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Kata sandi saat ini" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "dibuat" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Kegagalan Login Jejaring Sosial" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Terjadi kesalahan saat mencoba untuk masuk menggunakan akun jejaring sosial " "Anda." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Anda dapat masuk ke akun Anda menggunakan salah satu dari akun jejaring " "sosial berikut:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Anda saat ini tidak memiliki akun jejaring sosial terhubung ke akun ini." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Tambahkan Akun Pihak Ketiga" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Tambahkan Akun Pihak Ketiga" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Tambahkan Akun Pihak Ketiga" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Login Dibatalkan" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Anda memutuskan untuk membatalkan masuk ke situs kami menggunakan salah satu " "dari akun Anda. Jika ini adalah kesalahan, silakan lanjutkan ke masuk." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Akun sosial telah terhubung." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Akun sosial telah terputus." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Anda akan menggunakan akun %(provider_name)s untuk masuk ke\n" "%(site_name)s. Sebagai langkah akhir, silakan lengkapi formulir berikut:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Alamat E-mail" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Kata sandi saat ini" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Koneksi Akun" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Kata sandi harus memiliki panjang minimal {0} karakter." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Anda menerima e-mail ini karena Anda atau orang lain telah meminta kata " #~ "sandi untuk akun Anda.\n" #~ "Abaikan jika Anda tidak meminta reset kata sandi. Klik link di bawah " #~ "untuk mereset kata sandi Anda." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Alamat-alamat e-mail berikut ini terkait dengan akun Anda:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Konfirmasi Alamat E-mail" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Mohon masuk dengan salah satu\n" #~ "dari akun pihak ketiga Anda. Atau, %(link)sdaftar%(end_link)s\n" #~ "untuk akun %(site_name)s dan masuk di bawah:" #~ msgid "or" #~ msgstr "atau" #~ msgid "change password" #~ msgstr "ubah kata sandi" #~ msgid "OpenID Sign In" #~ msgstr "Masuk Dengan OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Alamat e-mail ini sudah terhubung dengan akun lain." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Kami telah mengirimkan e-mail. Mohon hubungi kami jika Anda tidak " #~ "menerimanya dalam beberapa menit." django-allauth-65.0.2/allauth/locale/it/000077500000000000000000000000001467545753200200255ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/it/LC_MESSAGES/000077500000000000000000000000001467545753200216125ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/it/LC_MESSAGES/django.po000066400000000000000000001501751467545753200234250ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Translators: # guglielmo , 2014 # joke2k , 2014 # puntosit , 2014 # Sandro , 2019. msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:29+0200\n" "Last-Translator: Sandro \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.8.7.1\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Questo account non è attualmente attivo." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Non puoi eliminare il tuo indirizzo email principale (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Questo indirizzo email è già associato a questo account." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "L'indirizzo email e/o la password che hai usato non sono corretti." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Un altro utente si è già registrato con questo indirizzo email." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Per favore digita la tua password attuale." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Codice errato." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Password errata." #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Token non valido" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Il codice per il reset della password non è valido." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Non puoi aggiungere più di %d indirizzi email." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Troppo tentativi di accesso. Riprova più tardi." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "L'indirizzo email non è assegnato a nessun account utente" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Dobbiamo verificare il tuo indirizzo email principale." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Questo username non può essere usato. Per favore scegline un altro." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Lo username e/o la password che hai usato non sono corretti." #: account/adapter.py:741 msgid "Use your password" msgstr "Usa la tua password" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "Usa la tua app di autenticazione" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "secret key" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Contrassegna gli indirizzi email selezionati come verificati." #: account/apps.py:11 msgid "Accounts" msgstr "Account" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Devi digitare la stessa password." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Password" #: account/forms.py:93 msgid "Remember Me" msgstr "Ricordami" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Indirizzo email" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "email" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Username" #: account/forms.py:123 msgid "Username or email" msgstr "Username o email" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Login" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Password dimenticata?" #: account/forms.py:299 msgid "Email (again)" msgstr "email (di nuovo)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Conferma dell'indirizzo emai" #: account/forms.py:311 msgid "Email (optional)" msgstr "email (opzionale)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Devi digitare la stessa password ogni volta." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Password (nuovamente)" #: account/forms.py:554 msgid "Current Password" msgstr "Password attuale" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nuova password" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nuova password (nuovamente)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Codice" #: account/models.py:26 msgid "user" msgstr "utente" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "indirizzo email" #: account/models.py:34 msgid "verified" msgstr "verificato" #: account/models.py:35 msgid "primary" msgstr "primario" #: account/models.py:41 msgid "email addresses" msgstr "indirizzo email" #: account/models.py:150 msgid "created" msgstr "creato" #: account/models.py:151 msgid "sent" msgstr "inviato" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "chiave" #: account/models.py:157 msgid "email confirmation" msgstr "email di conferma" #: account/models.py:158 msgid "email confirmations" msgstr "email di conferma" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Non è possibile aggiungere un indirizzo email a un account protetto da " "autenticazione a due fattori." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Non è possibile disattivare l'autenticazione a due fattori." #: mfa/adapter.py:38 #, fuzzy #| msgid "You cannot deactivate two-factor authentication." msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "Non è possibile disattivare l'autenticazione a due fattori." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Non è possibile attivare l'autenticazione a due fattori fino a quando non " "hai verificato il tuo indirizzo email." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "secret key" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Codici di recupero" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Autenticatore TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Codice autenticatore" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Password" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Esiste già un account con questo indirizzo email. Per favore entra con " "quell'account, e successivamente connetti il tuo account %s." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Token non valido" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Il tuo account non ha ancora nessuna password." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Non hai ancora verificato il tuo indirizzo email." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third-party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Puoi collegarti al tuo account utilizzando uno dei seguenti servizi di " "autenticazione Social Network:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Questo Social Account è già collegato ad un altro account." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Account" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "provider" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID del Provider" #: socialaccount/models.py:56 msgid "name" msgstr "nome" #: socialaccount/models.py:58 msgid "client id" msgstr "Id cliente" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID, o consumer key" #: socialaccount/models.py:63 msgid "secret key" msgstr "secret key" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Segreto API, segreto del cliente, or segreto del consumatore" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Chiave" #: socialaccount/models.py:81 msgid "social application" msgstr "applicazione sociale" #: socialaccount/models.py:82 msgid "social applications" msgstr "applicazioni sociali" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "Ultimo accesso" #: socialaccount/models.py:120 msgid "date joined" msgstr "data iscrizione" #: socialaccount/models.py:121 msgid "extra data" msgstr "dati aggiuntivi" #: socialaccount/models.py:125 msgid "social account" msgstr "account sociale" #: socialaccount/models.py:126 msgid "social accounts" msgstr "account sociali" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) o token di accesso (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token segreto" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) o token di aggiornamento (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "scade il" #: socialaccount/models.py:174 msgid "social application token" msgstr "token dell'applicazione social" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "token dell'applicazione social" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Dati profilo non validi" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Login" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Annulla" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Risposta non valida durante l'ottenimento del token di richiesta da \\\"%s\\" "\". La risposta è stata: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Risposta non valida alla richiesta di un token da \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Nessuna richiesta di token salvata per \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Nessun token di accesso salvato per \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Nessuna accesso alle risorse private a \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Risposta non valida alla richiesta di un token da \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Account non attivo" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Questo account non è attivo." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Conferma l'accesso" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Si prega di rieseguire l'autenticazione per proteggere il tuo account." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Opzioni alternative" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "email di conferma" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Inserisci un codice dell'autenticatore:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Conferma" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Accedi" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Indirizzi email" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "I seguenti indirizzi email sono associati al tuo account:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verificato" #: templates/account/email.html:29 msgid "Unverified" msgstr "Non verificato" #: templates/account/email.html:34 msgid "Primary" msgstr "Principale" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Rendi Principale" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Re-invia la Verifica" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Rimuovi" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Aggiungi un Indirizzo email" #: templates/account/email.html:70 msgid "Add Email" msgstr "Aggiungi email" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Sei sicuro di voler rimuovere l'indirizzo email selezionato?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "L'account esiste già" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Ciao da %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Grazie per usare %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Cancel Change" msgid "Email Changed" msgstr "Annulla Modifica" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Hai appena confermato l’indirizzo email %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "email di conferma" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "L'Utente %(user_display)s di %(site_domain)s ha registrato questo indirizzo " "email.\n" "Per confermare, clicca qui %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Conferma l'Indirizzo Email" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Rimuovi" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Accedi" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Password cambiata." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Password (nuovamente)" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Hai ricevuto questa mail perché hai richiesto la password per il tuo account " "utente.\n" "Se non hai richiesto tu il reset della password, ignora questa mail, " "altrimenti clicca sul link qui sotto per fare il reset della password." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Nel caso tu lo abbia dimenticato, il tuo nome utente è %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Email per re-impostare la password " #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Password cambiata." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Re-imposta la Password" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Password cambiata." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Re-imposta la Password" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Account" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Indirizzo email" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Email attuale" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Passare a" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "La tua email è ancora in attesa di verifica." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Annulla Modifica" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Passa a" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Cambia Email" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Conferma l'Indirizzo Email" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Conferma che %(email)s è un indirizzo email " "per l'utente %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Impossibile confermare %(email)s perché è già stata confermata da un account " "diverso." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Questo link di conferma email è scaduto o non è valido. Ti chiediamo di ripetere la richiesta di conferma via email." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "Se non hai ancora creato un account, %(link)sRegistrati%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Disconnetti" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Sei sicuro di volerti disconnettere?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Non puoi eliminare il tuo indirizzo email principale (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Abbiamo inviato una conferma all’indirizzo %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Hai appena confermato l’indirizzo email %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Indirizzo Email rimosso %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Ti sei collegato con successo come %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Ti sei scollegato." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Password cambiata con successo." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Password impostata correttamente." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Indirizzo email principale definito." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Cambia la tua Password" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Password dimenticata?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Hai dimenticato la tua password? Inserisci qui sotto l'indirizzo email con " "cui ti sei registrato, ti invieremo una mail con un link per re-impostarla." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Re-imposta la mia Password" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Se hai qualche problema a re-impostare la password, contattaci." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Ti abbiamo inviato un'email. Se non l'hai ricevuta, controlla nella cartella " "dello spam. Altrimenti, contattaci se non la ricevi entro qualche minuto." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Token non valido" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Il link di re-impostazione della password non è valido, probabilmente è già " "stato usato. Inoltra una nuova richiesta di " "re-impostazione della password." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Password cambiata." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Imposta una password" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Inserisci la tua password:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 #, fuzzy #| msgid "Recovery Codes" msgid "Request Code" msgstr "Codici di recupero" #: templates/account/request_login_code.html:30 #, fuzzy #| msgid "Alternative options" msgid "Other sign-in options" msgstr "Opzioni alternative" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registrati" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registrazione" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Hai già un account valido? %(link)sAccedi%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Registrazione" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Alternative options" msgid "Other options" msgstr "Opzioni alternative" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registrazioni Chiuse" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Spiacenti, le registrazioni sono per il momento sospese." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Nota" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Sei già collegato come %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Attenzione:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Non hai ancora indicato nessun indirizzo email. Devi inserirne uno se vuoi " "ricevere notifiche, recuperare la password, ecc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifica il tuo indirizzo Email" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Ti abbiamo inviato una email con un Link inserito all'interno. Per " "completare il procedimento di verifica clicca sul Link. Contattaci se non " "ricevi la mail entro qualche minuto." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Per utilizzare questa parte del sito dobbiamo verificare\n" "che sei veramente chi dici di essere. Sarà sufficiente\n" "dimostrare che hai effettivamente accesso al tuo indirizzo email. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Ti abbiamo inviato un messaggio email di verifica.\n" "Clicca sul link contenuto nella mail.\n" "Se non dovessi ricevere il messaggio entro qualche minuto, contattaci.\n" "Grazie." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Nota: Puoi cambiare in ogni " "momento l'indirizzo email usato per la registrazione." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Messaggi:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Connessioni all'account" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Autenticazione a Due Fattori" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sessioni" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Inserisci il codice dell'autenticatore: Il tuo account è protetto da " "autenticazione a due fattori." #: templates/mfa/email/recovery_codes_generated_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "È stato generato un nuovo set di codici di recupero." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 #, fuzzy #| msgid "Recovery Codes" msgid "New Recovery Codes Generated" msgstr "Codici di recupero" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Applicazione di autenticazione attivata." #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "Authenticator app activated." msgid "Authenticator App Activated" msgstr "Applicazione di autenticazione attivata." #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Applicazione di autenticazione disattivata." #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "Authenticator app deactivated." msgid "Authenticator App Deactivated" msgstr "Applicazione di autenticazione disattivata." #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "È stato generato un nuovo set di codici di recupero." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Hai appena confermato l’indirizzo email %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Applicazione di autenticazione" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "L'autenticazione tramite un'applicazione di autenticazione è attiva." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Un'applicazione di autenticazione non è attiva." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Disattiva" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Attiva" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Codici di recupero" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Ci sono %(unused_count)s codici di recupero disponibili su un totale di " "%(total_count)s." msgstr[1] "" "Ci sono %(unused_count)s codici di recupero disponibili su un totale di " "%(total_count)s." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Nessun codice di recupero impostato." #: templates/mfa/index.html:96 msgid "View" msgstr "Visualizza" #: templates/mfa/index.html:102 msgid "Download" msgstr "Scarica" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Genera" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "È stato generato un nuovo set di codici di recupero." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Inserisci un codice dell'autenticatore:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Stai per generare un nuovo set di codici di recupero per il tuo account." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Questa azione renderà invalidi i tuoi codici esistenti." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Sei sicuro?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Codici non utilizzati" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Scarica codici" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Genera nuovi codici" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Attiva l'applicazione di autenticazione" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Per proteggere il tuo account con l'autenticazione a due fattori, " "scannerizza il codice QR qui sotto con la tua applicazione di " "autenticazione. Successivamente, inserisci il codice di verifica generato " "dall'applicazione qui sotto." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Segreto dell'autenticatore" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Puoi conservare questo segreto e utilizzarlo per reinstallare la tua " "applicazione di autenticazione in un momento successivo." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Disattiva l'applicazione di autenticazione" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Stai per disattivare l'autenticazione basata sull'applicazione di " "autenticazione. Sei sicuro?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Sei sicuro di volerti disconnettere?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Non verificato" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "secret key" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Password attuale" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "creato" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Accesso Social fallito" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "C'è stato un errore mentre hai provato a collegarti con il tuo account " "Social Network." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Puoi collegarti al tuo account utilizzando uno dei seguenti servizi di " "autenticazione Social Network:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Non hai account di nessun Social Network collegato a questo account." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Aggiungi un account di un Social Network" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a Third-Party Account" msgid "Third-Party Account Connected" msgstr "Aggiungi un account di un Social Network" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a Third-Party Account" msgid "Third-Party Account Disconnected" msgstr "Aggiungi un account di un Social Network" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Connetti %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Stai per collegare un nuovo account di terze parti da %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Accedi tramite %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Stai per accedere utilizzando un account di terze parti da %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Continua" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Accesso annullato" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Hai deciso di cancellare l'accesso a questo sito usando uno dei tuoi account " "attivi. Se è stato un errore, ripeti l'Accesso." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "L'account Social Network è stato collegato." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Social Account scollegato." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Stai per usare il tuo account su %(provider_name)s per effettuare il login " "su\n" "%(site_name)s. Come ultima operazione ti chiediamo di riempire il form qui " "sotto:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "O usa un servizio di terze parti" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Disconnesso da tutte le altre sessioni." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Iniziato alle" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "Indirizzo IP" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Browser" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Ultimo accesso alle" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Attuale" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Esci dalle altre sessioni" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Sessioni utente" #: usersessions/models.py:92 msgid "session key" msgstr "chiave di sessione" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Connessioni all'account" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "La password deve essere lunga almeno {0} caratteri." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Stai ricevendo questa email perché tu o qualcun altro ha richiesto una\n" #~ "password per il tuo account utente. Tuttavia, non abbiamo alcun record di " #~ "un utente\n" #~ "con l'indirizzo email %(email)s nel nostro database.\n" #~ "\n" #~ "Questa email può essere ignorata in modo sicuro se non hai richiesto un " #~ "ripristino della password.\n" #~ "\n" #~ "Se sei stato tu, puoi registrarti per un account utilizzando il link qui " #~ "sotto." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "I seguenti indirizzi email sono associati al tuo account:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Conferma l'Indirizzo Email" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Per favore, accedi con uno\n" #~ "dei tuoi account social, o %(link)sregistra%(end_link)s\n" #~ "il tuo account per %(site_name)s e accedi:" #~ msgid "or" #~ msgstr "o" #~ msgid "change password" #~ msgstr "cambia password" #~ msgid "OpenID Sign In" #~ msgstr "Accesso con OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Questo indirizzo email è gia associato a un altro account." #~ msgid "" #~ "We have sent you an email. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Ti abbiamo spedito una mail. Contattaci se non la ricevi entro qualche " #~ "minuto." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Il login e/o la password che hai usato non sono corretti." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "Gli username possono contenere solo lettere, cifre e @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Questo username è già in uso. Per favore scegline un altro." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Accedi" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "email address for user %(user_display)s." #~ msgstr "" #~ "Hai appena confermato che %(email)s è un " #~ "indirizzo email valido per l'utente %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "Grazie per aver utilizzato questo Sito!" django-allauth-65.0.2/allauth/locale/ja/000077500000000000000000000000001467545753200200035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ja/LC_MESSAGES/000077500000000000000000000000001467545753200215705ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ja/LC_MESSAGES/django.po000066400000000000000000001602251467545753200234000ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-25 06:15+0000\n" "Last-Translator: SATOH Fumiyasu \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "このアカウントは現在無効です。" #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "メインのメールアドレスを削除することはできません。" #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "このメールアドレスはすでに登録されています。" #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "入力されたメールアドレスもしくはパスワードが正しくありません。" #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "他のユーザーがこのメールアドレスを使用しています。" #: account/adapter.py:62 msgid "Please type your current password." msgstr "現在のパスワードを入力してください。" #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "コードが正しくありません。" #: account/adapter.py:64 msgid "Incorrect password." msgstr "不正なパスワードです。" #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "不正または期限切れのキーです。" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "パスワードリセットトークンが無効です。" #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "メールアドレスは %d 個までしか登録できません。" #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "ログイン失敗が連続しています。時間が経ってからやり直してください。" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "このメールアドレスで登録されたユーザーアカウントがありません" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "メインのメールアドレスは確認済みでなければいけません。" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "このユーザー名は使用できません。他のユーザー名を選んでください。" #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "入力されたユーザー名もしくはパスワードが正しくありません。" #: account/adapter.py:741 msgid "Use your password" msgstr "パスワードを使用する" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "認証アプリまたは認証コードを利用する" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "セキュリティキーを使用" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "確認済みにするメールアドレスを選択" #: account/apps.py:11 msgid "Accounts" msgstr "アカウント" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "同じパスワードを入力してください。" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "パスワード" #: account/forms.py:93 msgid "Remember Me" msgstr "ログインしたままにする" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "メールアドレス" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "メールアドレス" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "ユーザー名" #: account/forms.py:123 msgid "Username or email" msgstr "ユーザー名またはメールアドレス" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "ログイン" #: account/forms.py:137 msgid "Forgot your password?" msgstr "パスワードをお忘れですか?" #: account/forms.py:299 msgid "Email (again)" msgstr "メールアドレス (確認用)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "メールアドレスの確認" #: account/forms.py:311 msgid "Email (optional)" msgstr "メールアドレス (オプション)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "同じパスワードを入力してください。" #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "パスワード (再入力)" #: account/forms.py:554 msgid "Current Password" msgstr "現在のパスワード" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "新しいパスワード" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "新しいパスワード (再入力)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "コード" #: account/models.py:26 msgid "user" msgstr "ユーザー" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "メールアドレス" #: account/models.py:34 msgid "verified" msgstr "確認済み" #: account/models.py:35 msgid "primary" msgstr "メイン" #: account/models.py:41 msgid "email addresses" msgstr "メールアドレス" #: account/models.py:150 msgid "created" msgstr "作成日時" #: account/models.py:151 msgid "sent" msgstr "送信日時" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "キー" #: account/models.py:157 msgid "email confirmation" msgstr "メールアドレスの確認" #: account/models.py:158 msgid "email confirmations" msgstr "メールアドレスの確認" #: headless/apps.py:7 msgid "Headless" msgstr "ヘッドレス" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "多要素認証で保護されているアカウントには、メールアドレスを追加できません。" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "多要素認証は無効化できません。" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "リカバリーキーを生成するには多要素認証の有効化が必要です。" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "メールアドレスの確認が完了するまで、多要素認証を有効にすることはできません。" #: mfa/adapter.py:141 msgid "Master key" msgstr "マスターキー" #: mfa/adapter.py:143 msgid "Backup key" msgstr "バックアップキー" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "キー番号 {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "多要素認証" #: mfa/models.py:24 msgid "Recovery codes" msgstr "リカバリーコード" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP 認証アプリ" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "認証アプリコード" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "パスワードレス" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "パスワードレス機能を有効化すると、このキーを使用してログイン可能になります。" "その代わりに生態認証や PIN コードなどによる保護が必要になります。" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "このメールアドレスを使用するアカウントが既にあります。そのアカウントにログイ" "ンしてから %s アカウントを接続してください。" #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "不正なトークンです。" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "アカウントにパスワードを設定する必要があります。" #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "確認済みのメールアドレスの登録が必要です。" #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "唯一残っている外部アカウントとの接続を解除することはできません。" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "この外部アカウントは他のアカウントに接続されています。" #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "外部アカウント" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "プロバイダー" #: socialaccount/models.py:52 msgid "provider ID" msgstr "プロバイダー ID" #: socialaccount/models.py:56 msgid "name" msgstr "ユーザー名" #: socialaccount/models.py:58 msgid "client id" msgstr "クライアント ID" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID もしくはコンシューマキー" #: socialaccount/models.py:63 msgid "secret key" msgstr "シークレットキー" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" "API シークレット、クライアントシークレット、またはコンシューマーシークレット" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "キー" #: socialaccount/models.py:81 msgid "social application" msgstr "ソーシャルアプリケーション" #: socialaccount/models.py:82 msgid "social applications" msgstr "ソーシャルアプリケーション" #: socialaccount/models.py:117 msgid "uid" msgstr "ユーザー名" #: socialaccount/models.py:119 msgid "last login" msgstr "最終ログイン" #: socialaccount/models.py:120 msgid "date joined" msgstr "アカウント作成日" #: socialaccount/models.py:121 msgid "extra data" msgstr "エクストラデータ" #: socialaccount/models.py:125 msgid "social account" msgstr "ソーシャルアカウント" #: socialaccount/models.py:126 msgid "social accounts" msgstr "ソーシャルアカウント" #: socialaccount/models.py:160 msgid "token" msgstr "トークン" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "「oauth_token」(OAuth1) もしくは Access Token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "トークンシークレット" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "「oauth_token_secret」(OAuth1) もしくは Refresh Token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "失効期限" #: socialaccount/models.py:174 msgid "social application token" msgstr "ソーシャルアプリケーショントークン" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "ソーシャルアプリケーショントークン" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "無効なプロファイルデータ" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "ログイン" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "キャンセル" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "リクエストトークン取得中に「%s」から不正な応答がありました。レスポンス: %s" #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "" "不正なレスポンスが返されたため、「%s」からアクセストークンを取得できませんで" "した。" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "「%s」のリクエストトークンを保存できませんでした。" #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "「%s」のアクセストークンを保存できませんでした。" #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "「%s」の情報にアクセスできませんでした。" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "" "不正なレスポンスが返されたため、「%s」からリクエストトークンを取得できません" "でした。" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "無効なアカウント" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "このアカウントは無効です。" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "アクセス確認" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "アカウントを保護するために再認証してください。" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "そのほかの方法" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "メールアドレスの確認" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "メールの確認コードを入力:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "コードを %(email_link)s に送信しました。コードの有効期限はまもなく切れますの" "で、お早めにご入力ください。" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "確認する" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "ログイン" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "ログインコードを入力" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "メールアドレス" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "以下のメールアドレスがアカウントに登録されています:" #: templates/account/email.html:25 msgid "Verified" msgstr "確認済み" #: templates/account/email.html:29 msgid "Unverified" msgstr "未確認" #: templates/account/email.html:34 msgid "Primary" msgstr "メイン" #: templates/account/email.html:44 msgid "Make Primary" msgstr "メインにする" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "確認メールを再送する" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "削除" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "メールアドレスの登録" #: templates/account/email.html:70 msgid "Add Email" msgstr "メールアドレスの登録" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "選択されたメールアドレスを削除してもよろしいですか?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "このメールを受信しているのは、あなたまたは誰かが次のメールアドレスを使用して" "アカウントの登録を試みたためです:\n" "\n" "%(email)s\n" "\n" "しかし、このメールアドレスを使用したアカウントがすでに存在しています。もしア" "カウントの登録を忘れていた場合は、パスワードを忘れたときの手続きを利用してア" "カウントを回復してください:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "アカウントが既に存在" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "こんにちは、%(site_name)s です!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "%(site_name)s を利用いただきありがとうございます!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "あなたのアカウントに以下の変更が加えられたため、このメールが届いています:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "この変更が認識できない場合は、直ちに適切なセキュリティ対策を講じてください。" "あなたのアカウントに対するこの変更の起源は以下の通りです:\n" "\n" "- IPアドレス: %(ip)s\n" "- ブラウザ: %(user_agent)s\n" "- 日付: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" "あなたのメールアドレスを %(from_email)s から %(to_email)s に変更しました。" #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "メールアドレスを変更しました" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "あなたのメールアドレスを確認しました。" #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "メールアドレスの確認" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "%(user_display)s さんが %(site_domain)s にあなたのメールアドレスを登録しよう" "としています。" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "あなたのメール確認コードを下記に記載します。開いているブラウザのウィンドウに" "入力してください。" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "間違いなければ、%(activate_url)s にアクセスしてください。" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "メールアドレスを確認してください" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" "メールアドレス %(deleted_email)s をあなたのアカウントから削除しました。" #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "メールアドレスの削除" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "以下にあなたのログインコードが記載されています。開いているブラウザのウィンド" "ウに入力してください。" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "この操作があなたによるものではない場合、このメールは無視しても差し支えありま" "せん。" #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "ログインコード" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "パスワードを変更しました。" #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "パスワードを変更しました" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "このメールは、あなた (もしくは別の誰か) がパスワードの再設定を行おうとしたた" "めに送られました。\n" "パスワードの再設定を要求したのがあなたではない場合、このメールは無視してくだ" "さい。\n" "パスワードを再設定するためには、以下のリンクをクリックしてください。" #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "あなたのアカウントのユーザー名は %(username)s です。" #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "パスワード再設定メール" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "パスワードをリセットしました。" #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "パスワード再設定" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "パスワードを設定しました。" #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "パスワード設定" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "このメールは、あなたまたは他の誰かが %(email)s のメールアドレスを持つアカウン" "トにアクセスしようとしたために送信されています。ただし、私たちのデータベース" "にはそのようなアカウントの記録はありません。" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "もしあなたで間違いないなら、以下のリンクからアカウントを登録できます。" #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "不明なアカウント" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "メールアドレス" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "現在のメールアドレス" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "変更中" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "あなたのメールアドレスはまだ確認されていません。" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "変更をキャンセル" #: templates/account/email_change.html:49 msgid "Change to" msgstr "変更する" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "メールアドレス変更" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "メールアドレスの確認" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "メールアドレス %(email)s がユーザー " "%(user_display)s さんのものであることを確認してください。" #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "%(email)s はすでにほかのアカウントで確認済みです。" #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "メールアドレス確認用のリンクが不正か、期限が切れています。確認用のメールを再送してください。" #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "アカウントをまだお持ちでなければ、 %(link)sこちらからユーザー登" "録%(end_link)s してください。" #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "パスキーでログイン" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "ログインコードをメールする" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "ログアウト" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "ログアウトしますか?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "メインのメールアドレス (%(email)s) を削除することはできません。" #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "確認メールを %(email)s へ送信しました。" #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s を確認しました。" #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "メールアドレス %(email)s を削除しました。" #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "ユーザー %(name)s としてログインしました。" #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "ログアウトしました。" #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "%(email)s にログインコードを送信しました。" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "パスワードを変更しました。" #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "パスワードを設定しました。" #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "メインメールアドレスを設定しました。" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "パスワード変更" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "パスワードをお忘れですか?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "パスワードをお忘れですか? パスワードをリセットするために、メールアドレスを入" "力してください。" #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "パスワードをリセット" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "パスワードの再設定に問題がある場合はご連絡ください。" #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "確認のためのメールを送信しました。受信できない場合は、スパムフォルダをご確認" "ください。数分以内にメールが届かない場合はご連絡ください。" #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "不正なトークン" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "パスワード再設定用のリンクが不正です。すでに使用された可能性があります。もう" "一度 パスワードの再設定をお試しくださ" "い。" #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "パスワードを変更しました。" #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "パスワード設定" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "パスワードを入力してください。" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "パスワード不要のログイン用特別コードが記載されたメールをお送りします。" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "コードを要求" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "そのほかのログイン方法" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "ユーザー登録" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "ユーザー登録" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "すでにアカウントをお持ちであれば、こちらから %(link)sログイン%(end_link)s し" "てください。" #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "パスキーでユーザー登録" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "パスキーでユーザー登録" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "ほかのオプション" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "ユーザー登録停止中" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "申し訳ありません、現在ユーザー登録を停止しています。" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "注意" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "%(user_display)s さんとしてすでにログイン中です。" #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "注意:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "メールアドレスが設定されていません。通知を受け取ったり、パスワードをリセット" "したりするためにはメールアドレスを登録する必要があります。" #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "メールアドレスを確認してください" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "確認のメールを送信しました。メールに記載されたリンクをクリックして、ユーザー" "登録を完了させてください。数分待っても確認のメールが届かない場合はご連絡くだ" "さい。" #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "このページにアクセスするためには、本人確認が必要です。\n" "そのために、登録されているメールアドレスがご自身のものであることを確認してい" "ただきます。 " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "確認のためのメールを送信しました。メールに記載されたリンクをクリックしてくだ" "さい。\n" "確認メールが受信ボックスに見つからない場合は、迷惑メールフォルダをチェックし" "てください。\n" "数分以内にメールが届かない場合はご連絡ください。" #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "注意: メールアドレスの変更をし" "ていただくことも可能です。" #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "メッセージ:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "メニュー:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "アカウント接続" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "多要素認証" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "セッション" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "あなたのアカウントは多要素認証で保護されています。認証コードを入力してくださ" "い:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "多要素認証用のリカバリーコードを新たに生成しました。" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "新しいリカバリーコードを生成しました" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "認証アプリを有効化しました。" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "認証アプリを有効化しました" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "認証アプリを無効化しました。" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "認証アプリを無効化しました" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "新しいセキュリティキーを登録しました。" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "セキュリティキーを追加しました" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "セキュリティキーを削除しました。" #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "セキュリティキーを削除しました" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "認証アプリ" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "認証アプリを使用した認証が有効です。" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "認証アプリは有効ではありません。" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "無効化する" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "有効化する" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "セキュリティキー" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "%(count)s 個のセキュリティキーを登録しました。" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "登録されているセキュリティキーはありません。" #: templates/mfa/index.html:62 msgid "Manage" msgstr "管理" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "登録" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "リカバリーコード" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "利用可能なリカバリーコードは %(total_count)s 個中 %(unused_count)s 個です。" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "リカバリーコードが設定されていません。" #: templates/mfa/index.html:96 msgid "View" msgstr "表示" #: templates/mfa/index.html:102 msgid "Download" msgstr "ダウンロード" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "生成する" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "新しいリカバリーコードを生成しました。" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "セキュリティーキーを登録しました。" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "セキュリティキーを削除しました。" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "認証アプリのコードを入力:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "新しいリカバリーコードセットを生成しようとしています。" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "この操作により、現在のコードが無効になります。" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "本当によろしいですか?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "未使用のコード" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "コードをダウンロードする" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "新しいコードを生成する" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "認証アプリを有効化する" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "アカウントを多要素認証で保護するために、認証アプリで以下の QR コードをスキャ" "ンしてください。次に、アプリで生成された確認コードを以下に入力してください。" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "認証アプリシークレット" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "このシークレットを保存し、後で認証アプリを再インストールする際に使用できま" "す。" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "認証アプリを無効化する" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "認証アプリによる認証を無効化しようとしています。本当によろしいですか?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "セキュリティキーを追加" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "セキュリティキーを解除" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "セキュリティキーを解除しますか?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "使用方法" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "パスキー" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "セキュリティキー" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "このキーはパスキーかどうか示されていません。" #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "未指定" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "登録日: %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "最終使用日: %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "編集" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "セキュリティキーを編集" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "保存" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "パスキーを作成" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "あなたのアカウント用のパスキーを作成します。あとでキーの追加もできるため、キ" "ーを区別しやすい名前を付けてください。" #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "作成" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "この機能を利用するには JavaScript が必要です。" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "外部アカウントによるログインに失敗しました" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "外部アカウントでのログイン時ににエラーが発生しました。" #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "以下の外部アカウントを使ってログインできます:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "あなたのカウントに結びつけられた外部アカウントはありません。" #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "外部アカウントを追加する" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "%(provider)s の外部アカウントをあなたのアカウントに接続しました。" #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "外部アカウントを接続しました" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "%(provider)s の外部アカウントへの接続を解除しました。" #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "外部アカウントとの接続を解除しました" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "%(provider)s と接続する" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "%(provider)s の新しい外部アカウントを接続しようとしています。" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "%(provider)s でログイン" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "%(provider)s の外部アカウントを使用してログインしようとしています。" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "続ける" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "ログインをキャンセルしました" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "既存の外部アカウントを使ったログインをキャンセルしました。\n" "やり直す場合はログインページにお進みください。" #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "外部アカウントを接続しました。" #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "外部アカウントとの接続を解除しました。" #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "%(provider_name)s アカウントを使って %(site_name)s にログインしようとしていま" "す。\n" "ユーザー登録のために、以下のフォームに記入してください。" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "外部アカウントを使用する" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "他のすべてのセッションからログアウトしました。" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "開始日時" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP アドレス" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "ブラウザー" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "閲覧日時" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "現在の" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "他のセッションをログアウト" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "ユーザーセッション" #: usersessions/models.py:92 msgid "session key" msgstr "セッションキー" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "アカウント接続" #~ msgid "Use security key or device" #~ msgstr "セキュリティキー/デバイスを使用" #~ msgid "Add Security Key or Device" #~ msgstr "セキュリティキー/デバイスの登録" #~ msgid "Add key or device" #~ msgstr "キー/デバイスを登録" #~ msgid "Security Keys and Devices" #~ msgstr "セキュリティキー/デバイス" #~ msgid "You have not added any security keys/devices." #~ msgstr "登録されたセキュリティキー/デバイスはありません。" #~ msgid "Edit Security Key or Device" #~ msgstr "セキュリティキー/デバイスの編集" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "パスワードは {0} 文字以上の長さが必要です。" #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "このメールは、あなた(もしくは別の誰か)がパスワードの再設定を行おうとした" #~ "ために送られました。\n" #~ "パスワードの再設定を要求したのがあなたではない場合、このメールは無視してく" #~ "ださい。パスワードを再設定するためには、以下のリンクをクリックしてくださ" #~ "い。" #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "以下のメールアドレスがアカウントに登録されています:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "メールアドレスの確認" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "お持ちの外部アカウントでログインするか、%(site_name)sに ユーザー登録 してログインしてください。" #~ msgid "or" #~ msgstr "または" #~ msgid "change password" #~ msgstr "パスワード変更" #~ msgid "OpenID Sign In" #~ msgstr "OpenID ログイン" #~ msgid "This email address is already associated with another account." #~ msgstr "このメールアドレスは別のアカウントで使用されています。" django-allauth-65.0.2/allauth/locale/ka/000077500000000000000000000000001467545753200200045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ka/LC_MESSAGES/000077500000000000000000000000001467545753200215715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ka/LC_MESSAGES/django.po000066400000000000000000001774141467545753200234110ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Nikoloz Naskidashvili , 2021. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:31+0200\n" "Last-Translator: Nikoloz Naskidashvili \n" "Language-Team: LANGUAGE \n" "Language: ka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "ეს ანგარიში ამჟამად გაუქმებულია." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "შენ არ შეგიძლია წაშალო შენი პირველადი ელ. ფოსტა (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "ეს ელ.ფოსტის მისამართი უკვე დაკავშირებულია ამ ანგარიშთან." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "თქვენს მიერ მითითებული ელ. ფოსტა ან პაროლი არასწორია." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "მომხმარებელი ამ ელ. ფოსტით უკვე დარეგისტრირებულია." #: account/adapter.py:62 msgid "Please type your current password." msgstr "გთხოვთ აკრიფეთ მიმდინარე პაროლი." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "მიმდინარე პაროლი" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "შეცდომა, ცუდი კოდი" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "პაროლის აღდგენის კოდი არასწორია." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "თქვენ არ შეგიძლიათ დაამატოთ %d- ზე მეტი ელექტრონული ფოსტის მისამართი." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "შესვლის ძალიან ბევრი წარუმატებელი მცდელობა. მოგვიანებით სცადეთ." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "" "ეს ელექტრონული ფოსტის მისამართი არ არის მიბმული რომელიმე მომხმარებლის " "ანგარიშზე" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "თქვენი პირველადი ელ. ფოსტა უნდა იყოს დადასტურებული" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "ამ მომხმარებლის სახელის გამოყენება შეუძლებელია. გთხოვთ გამოიყენოთ სხვა." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "თქვენს მიერ მითითებული მომხმარებლის სახელი ან პაროლი არასწორია." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "დაგავიწყდა პაროლი?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "საიდუმლო კოდი" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "საიდუმლო კოდი" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "თქვენი პირველადი ელ. ფოსტა უნდა იყოს დადასტურებული" #: account/apps.py:11 msgid "Accounts" msgstr "მომხმარებლის ანგარიშები" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "თქვენ უნდა აკრიფოთ ერთი და იგივე პაროლი ყოველ ჯერზე." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "პაროლი" #: account/forms.py:93 msgid "Remember Me" msgstr "დამიმახსოვრე" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "ელ. ფოსტა" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "ელ. ფოსტა" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "მომხმარებლის სახელი" #: account/forms.py:123 msgid "Username or email" msgstr "მომხმარებლის სახელი ან ელ. ფოსტა" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "შესვლა" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "დაგავიწყდა პაროლი?" #: account/forms.py:299 msgid "Email (again)" msgstr "ელ. ფოსტა (გაამეორეთ)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "ელ. ფოსტის დადასტურება" #: account/forms.py:311 msgid "Email (optional)" msgstr "ელ. ფოსტა (არ არის აუცილებელი)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "თქვენ უნდა ჩაწეროთ ერთი და იგივე ელ. ფოსტა ყოველ ჯერზე." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "პაროლი (გაამეორეთ)" #: account/forms.py:554 msgid "Current Password" msgstr "მიმდინარე პაროლი" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "ახალი პაროლი" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "ახალი პაროლი (გაამეორეთ)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "მომხმარებელი" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "ელ. ფოსტა" #: account/models.py:34 msgid "verified" msgstr "დადასტურებული" #: account/models.py:35 msgid "primary" msgstr "პირველადი" #: account/models.py:41 msgid "email addresses" msgstr "ელ. ფოსტის ანგარიშები" #: account/models.py:150 msgid "created" msgstr "შექმნილი" #: account/models.py:151 msgid "sent" msgstr "გაგზავნილი" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "კოდი" #: account/models.py:157 msgid "email confirmation" msgstr "ელ. ფოსტის დადასტურება" #: account/models.py:158 msgid "email confirmations" msgstr "ელ. ფოსტის დადასტურებები" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "საიდუმლო კოდი" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "პაროლი" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "მომხმარებელი უკვე არსებობს ამ ელ.ფოსტის მისამართით.%s-ით შესვლა ვერ " "მოხერხდება." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "შეცდომა, ცუდი კოდი" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "თქვენს ანგარიშს არ აქვს პაროლი დაყენებული." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "თქვენს ანგარიშს არ აქვს დადასტურებული ელ. ფოსტა." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "თქვენ შეგიძლიათ შეხვიდეთ თქვენს ანგარიშში რომელიმე შემდეგი სოციალური " "ანგარიშის გამოყენებით:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "ეს სოციალური ანგარიში უკვე მიბმულია სხვა მომხმარებლის ანგარიშთან." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "სოციალური ანგარიშები" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "პროვაიდერი" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "პროვაიდერი" #: socialaccount/models.py:56 msgid "name" msgstr "სახელი" #: socialaccount/models.py:58 msgid "client id" msgstr "კლიენტის id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "აპლიკაციის ID ან მომხმარებლის კოდი" #: socialaccount/models.py:63 msgid "secret key" msgstr "საიდუმლო კოდი" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" "API-ს საიდუმლო კოდი, კლიენტის საიდუმლო კოდი ან მომხმარებლის საიდუმლო კოდი" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "კოდი" #: socialaccount/models.py:81 msgid "social application" msgstr "სოციალური აპლიკაცია" #: socialaccount/models.py:82 msgid "social applications" msgstr "სოციალური აპლიკაციები" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "ბოლო შესვლის თარიღი" #: socialaccount/models.py:120 msgid "date joined" msgstr "ანგარიშის შექმნის თარიღი" #: socialaccount/models.py:121 msgid "extra data" msgstr "სხვა მონაცემები" #: socialaccount/models.py:125 msgid "social account" msgstr "სოციალური ანგარიში" #: socialaccount/models.py:126 msgid "social accounts" msgstr "სოციალური ანგარიშები" #: socialaccount/models.py:160 msgid "token" msgstr "კოდი" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ან access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "საიდუმლო კოდი" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ან refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "ვადა გაუსვლის თარიღი" #: socialaccount/models.py:174 msgid "social application token" msgstr "სოციალური ანგარიშის კოდი" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "სოციალური ანგარიშების კოდი" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "პროფილის მონაცემები არასწორია" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "შესვლა" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "არასწორი პასუხი მოთხოვნის მიღებისას \"%s\"-დან." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "არასწორი პასუხი მოთხოვნის მიღებისას \"%s\"-დან." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "მოთხოვნის კოდი არ არის შენახული \"%s\" -სთვის." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "მოთხოვნის წვდომის კოდი არ არის შენახული \"%s\" -სთვის." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\" - ზე კერძო რესურსებზე წვდომა არ არის." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "არასწორი პასუხი მოთხოვნის მიღებისას \"%s\"-დან." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "ანგარიში გაუქმებულია" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "ეს ანგარიში გაუქმებულია" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "დაადასტურეთ ელ. ფოსტა" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "ელ. ფოსტის დადასტურება" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "საიდუმლო კოდი" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "დადასტურება" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "შესვლა" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "ელ. ფოსტის მისამართები" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "შემდეგი ელ.ფოსტის მისამართები ასოცირდება თქვენს ანგარიშთან:" #: templates/account/email.html:25 msgid "Verified" msgstr "დადასტურებული" #: templates/account/email.html:29 msgid "Unverified" msgstr "არ არის დადასტურებელი" #: templates/account/email.html:34 msgid "Primary" msgstr "პირველადი" #: templates/account/email.html:44 msgid "Make Primary" msgstr "გახადე პირველადი" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "ვერიფიკაციის თავიდან გაგზავნა" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "წაშლა" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "ელ. ფოსტის მისამართის დამატება" #: templates/account/email.html:70 msgid "Add Email" msgstr "ელ. ფოსტის დამატება" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "ნამდვილად გსურთ წაშალოთ არჩეული ელ.ფოსტის მისამართი?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "მოგესალმებით %(site_name)s!-დან" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "მადლობა რომ იყენებ %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "ელ. ფოსტა" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "თქვენ დაადასტურეთ %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "ელ. ფოსტის დადასტურება" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "თქვენ იღებთ ამ ელ. წერილს რადგან მომხმარებემა - %(user_display)s მიუთითა " "თქვენი ელ.ფოსტის ანგარიში რომ დარეგისტრირდეს შემდეგ საიტზე - " "%(site_domain)s.\n" "\n" "იმისთვის, რომ დაადასტუროთ ეს, გადადით შემდეგ ლინკზე %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "გთხოვთ დაადასტუროთ თქვენი ელ. ფოსტა" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "წაშლა" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "შესვლა" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "თქვენი პაროლი შეცვლილია" #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "პაროლი (გაამეორეთ)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "თქვენ იღებთ ამ ელ. წერილს რადგან თქვენ ან სხვა ვიღაცამ მოითხოვა პაროლის " "შეცვლა თქვენს ანგარიშზე.\n" "თქვენ შეგიძლიათ უბრალოდ დააიგნოროთ ეს ელ. წერილი თუ ეს თქვენი მოთხოვნა არ " "იყო. დააჭირეთ ქვემოთ მოცემულ ლინკს პაროლის აღსადგენად." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "თუ თქვენ დაგავიწყდათ, თქვენი მომხმარებლის სახელია: %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "პაროლის აღდგენის ელ. წერილი" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "თქვენი პაროლი შეცვლილია" #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "პაროლის შეცვლა" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "თქვენი პაროლი შეცვლილია" #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "პაროლის შეცვლა" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "მომხმარებლის ანგარიშები" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "ელ. ფოსტის მისამართები" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "მიმდინარე პაროლი" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "თქვენი პირველადი ელ. ფოსტა უნდა იყოს დადასტურებული" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "ელ. ფოსტა" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "ელ. ფოსტა" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "დაადასტურეთ ელ. ფოსტა" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "გთხოვთ დაადასტურეთ, რომ %(email)s არის ელ. " "ფოსტის მისამართი მომხმარებლისთვის: %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "ეს სოციალური ანგარიში უკვე მიბმულია სხვა მომხმარებლის ანგარიშთან." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "ეს ელ. ფოსტის დადასტურების ლინკი არასწორია ან ვადაგასულია. გთხოვთ გააკეთოთ ახალი მოთხოვნა." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "თუ არ გაქვთ შექმნილი ანგარიში, მაშინ გთხოვთ " "%(link)sდარეგისტრირდით%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "გასვლა" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "დარწმუნებული ხარ, რომ გინდა გასვლა?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "შენ არ შეგიძლია წაშალო შენი პირველადი ელ. ფოსტა (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "ელ. ფოსტის დადასტურების წერილი გაგზავნილია %(email)s მისამართით." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "თქვენ დაადასტურეთ %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "ელ. ფოსტა %(email)s წაშლილია." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "თქვენ წარმატებით შეხვედით %(name)s-ად." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "თქვენ წარმატებით გახვედით თქვენი ანგარიშიდან." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "პაროლი წარმატებით შეცვლილია." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "პაროლი წარმატებით დაყენებულია." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "პირველადი ელ. ფოსტა წარმატებით დაყენებულია" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "პაროლის შეცვლა" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "დაგავიწყდა პაროლი?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "დაგავიწყდათ თქვენი პაროლი? ჩაწერეთ თქვენი ელ. ფოსტა ქვემოთ და ჩვენ " "გამოგიგზავნით ელ. წერილს აღსადგენად." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "ჩემი პაროლის შეცვლა" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "გთხოვთ დაგვიკავშირდით თუ გაქვთ პრობლემა პაროლის შეცვლასთან." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "ჩვენ გამოგიგზავნეთ ელ. წერილი\n" "ვერიფიკაციისთვის. გთხოვთ მიჰყევით მასში მოცემულ ლინკს. გთხოვთ\n" "გთხოვთ დაგვიკავშირდით თუ არ მიიღებთ მას რამდენიმე წუთში." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "შეცდომა, ცუდი კოდი" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "პაროლის აღდგენის ლინკი არასწორია, ალბათ იმის გამო რომ უკვე გამოყენებული " "იქნა. გთხოვთ მოითხოვეთ პაროლის შეცვლა " "თავიდან." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "თქვენი პაროლი შეცვლილია" #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "პაროლის დაყენება" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "დაგავიწყდა პაროლი?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "რეგისტრაცია" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "რეგისტრაცია" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "უკვე გაქვს ანგარიში? %(link)sშესვლა%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "რეგისტრაცია" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "რეგისტრაცია დროებით გაუქმებულია" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "ბოდიში, რეგისტრაცია დროებით გაუქმებულია" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "შენიშვნა" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "თქვენ უკვე ხართ შესული როგორც %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "გაფრთხილება:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "თქვენ ამჟამად არ გაქვთ რაიმე ელ.ფოსტის მისამართი დაყენებული. უნდა დაამატოთ " "ელექტრონული ფოსტის მისამართი, რათა მიიღოთ შეტყობინებები, აღადგინოთ პაროლი და " "ა.შ." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "დაადასტურეთ თქვენი ელ. ფოსტა" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "ჩვენ გამოგიგზავნეთ ელ. წერილი ვერიფიკაციისთვის. მიჰყევით მასში მოცემულ " "ლინკს, რომ დაასრულოთ რეგისტრაცია. გთხოვთ დაგვიკავშირდით თუ არ მიიღებთ მას " "რამდენიმე წუთში." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "საიტის ეს ნაწილი ითხოვს იმის დადასტურებას, რომ\n" "თქვენ ხართ ის, ვინც აცხადებთ, რომ ხართ. ამიტომ ჩვენ ვითხოვთ\n" "თქვენი ელ. ფოსტის მისამართის საკუთრების დადასტურებას. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "ჩვენ გამოგიგზავნეთ ელ. წერილი\n" "ვერიფიკაციისთვის, მიჰყევით მასში მოცემულ ლინკს. გთხოვთ\n" "დაგვიკავშირდით თუ არ მიიღებთ მას რამდენიმე წუთში." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "შენიშვნა: თქვენ ჯერ კიდეგ შეგიძლიათ შეცვალოთ ელ. ფოსტის მისამართო." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "ანგარიშის კავშირები" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "საიდუმლო კოდი" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "საიდუმლო კოდი" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "თქვენ დაადასტურეთ %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "საიდუმლო კოდი" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "საიდუმლო კოდი" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "საიდუმლო კოდი" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "საიდუმლო კოდი" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "დარწმუნებული ხარ, რომ გინდა გასვლა?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "საიდუმლო კოდი" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "არ არის დადასტურებელი" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "საიდუმლო კოდი" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "მიმდინარე პაროლი" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "შექმნილი" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "შეცდომა სოციალური ანგარიშით შესვლისას" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "დაფიქსირდა შეცდომა სოციალური ანგარიშით შესვლის დროს." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "თქვენ შეგიძლიათ შეხვიდეთ თქვენს ანგარიშში რომელიმე შემდეგი სოციალური " "ანგარიშის გამოყენებით:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "თქვენ ამჟამად არ გაქვთ ამ ანგარიშთან დაკავშირებული სოციალური ქსელის " "ანგარიშები." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "სოციალური ანგარიშის დამატება" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "სოციალური ანგარიშის დამატება" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "სოციალური ანგარიშის დამატება" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "%(provider)s ანგარიშის დაკავშირება" #: templates/socialaccount/login.html:13 #, fuzzy, python-format #| msgid "" #| "You are about to connect a new third party account from %(provider)s." msgid "You are about to connect a new third-party account from %(provider)s." msgstr "თქვენ აპირებთ დააკავშიროთ %(provider)s ანგარიში." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "შესვლა %(provider)s ანგარიშით" #: templates/socialaccount/login.html:20 #, fuzzy, python-format #| msgid "" #| "You are about to sign in using a third party account from %(provider)s." msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "თქვენ აპირებთ შესვლას %(provider)s ანგარიშით." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "გაგრძელება" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "შესვლა გაუქმებულია" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "თქვენ გადაწყვიტეთ გააუქმოთ შესვლა ჩვენს საიტზე თქვენი ერთ-ერთი არსებული " "ანგარიშის გამოყენებით. თუ ეს შეცდომა იყო, გთხოვთ ხელახლა შედით." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "სოციალური ანგარიში მიბმულია." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "სოციალური ანგარიში გაუქმებულია." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "თქვენ აპირებთ გამოიყენოთ თქვენი %(provider_name)s ანგარიში შესასვლელად\n" "%(site_name)s-ზე. როგორც საბოლოო ნაბიჯი, გთხოვთ შეავსეთ ეს ფორმა:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "ელ. ფოსტის მისამართები" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "მიმდინარე პაროლი" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "ანგარიშის კავშირები" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "პაროლი უნდა შეიცავდეს მინიმუმ {0} სიმბოლოს." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "თქვენ იღებთ ამ ელ. წერილს რადგან თქვენ ან სხვა ვიღაცამ მოითხოვა პაროლის " #~ "შეცვლა თქვენს ანგარიშზე.\n" #~ "თქვენ შეგიძლიათ უბრალოდ დააიგნოროთ ეს ელ. წერილი თუ ეს თქვენი მოთხოვნა არ " #~ "იყო. დააჭირეთ ქვემოთ მოცემულ ლინკს პაროლის აღსადგენად." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "შემდეგი ელ.ფოსტის მისამართები ასოცირდება თქვენს ანგარიშთან:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "დაადასტურეთ ელ. ფოსტა" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "გთხოვთ შედით რომელიმე\n" #~ "სოციალური ანგარიშით. ან, %(link)sდარეგისტრირდით %(end_link)s\n" #~ "ან შედით %(site_name)s საიტზე" #~ msgid "or" #~ msgstr "ან" #~ msgid "change password" #~ msgstr "პაროლის შეცვლა" #~ msgid "OpenID Sign In" #~ msgstr "OpenID-ით შესვლა" #~ msgid "This email address is already associated with another account." #~ msgstr "ეს ელ.ფოსტის მისამართი უკვე დაკავშირებულია სხვა ანგარიშთან." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "ჩვენ გამოგიგზავნეთ ელ. წერილი. გთხოვთ დაგვიკავშირდით თუ არ მიიღებთ " #~ "რამდენიმე წუთში." django-allauth-65.0.2/allauth/locale/ko/000077500000000000000000000000001467545753200200225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ko/LC_MESSAGES/000077500000000000000000000000001467545753200216075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ko/LC_MESSAGES/django.po000066400000000000000000001442631467545753200234230ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:50+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "해당 계정은 현재 비활성화 상태입니다." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "주 이메일은 제거할 수 없습니다." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "해당 이메일은 이미 이 계정에 등록되어 있습니다." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "이메일 또는 비밀번호가 올바르지 않습니다." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "해당 이메일은 이미 사용되고 있습니다." #: account/adapter.py:62 msgid "Please type your current password." msgstr "현재 비밀번호를 입력하세요." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "올바르지 않은 코드." #: account/adapter.py:64 msgid "Incorrect password." msgstr "올바르지 않은 비밀번호." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "올비르지 않거나 만료된 키." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "비밀번호 초기화 토큰이 올바르지 않습니다." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "이메일 주소는 %d개 이상 추가할 수 없습니다." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "너무 많은 로그인 실패가 감지되었습니다. 잠시 후에 다시 시도하세요." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "해당 이메일을 가지고 있는 사용자가 없습니다." #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "주 이메일은 인증이 필요합니다." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "해당 아이디는 이미 사용중입니다. 다른 사용자명을 이용해 주세요." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "아이디 또는 비밀번호가 올바르지 않습니다." #: account/adapter.py:741 msgid "Use your password" msgstr "비밀번호를 사용하세요" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "인증 앱 또는 코드를 사용하세요" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "보안키를 사용하세요" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "선택된 이메일 주소를 인증됨으로 표시" #: account/apps.py:11 msgid "Accounts" msgstr "계정" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "동일한 비밀번호를 입력해야 합니다." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "비밀번호" #: account/forms.py:93 msgid "Remember Me" msgstr "아이디 저장" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "이메일 주소" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "이메일" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "아이디" #: account/forms.py:123 msgid "Username or email" msgstr "아이디 또는 이메일" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "로그인" #: account/forms.py:137 msgid "Forgot your password?" msgstr "비밀번호를 잊으셨나요?" #: account/forms.py:299 msgid "Email (again)" msgstr "이메일 (확인)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "이메일 주소 확인" #: account/forms.py:311 msgid "Email (optional)" msgstr "이메일 (선택사항)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "동일한 이메일을 입력해야 합니다." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "비밀번호 (확인)" #: account/forms.py:554 msgid "Current Password" msgstr "현재 비밀번호" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "새 비밀번호" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "새 비밀번호 (확인)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "코드" #: account/models.py:26 msgid "user" msgstr "사용자" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "이메일 주소" #: account/models.py:34 msgid "verified" msgstr "인증완료" #: account/models.py:35 msgid "primary" msgstr "주" #: account/models.py:41 msgid "email addresses" msgstr "이메일 주소" #: account/models.py:150 msgid "created" msgstr "생성됨" #: account/models.py:151 msgid "sent" msgstr "전송됨" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "키" #: account/models.py:157 msgid "email confirmation" msgstr "이메일 확인" #: account/models.py:158 msgid "email confirmations" msgstr "이메일 확인" #: headless/apps.py:7 msgid "Headless" msgstr "헤드리스" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "2단계 인증으로 보호되는 계정에 이메일 주소를 추가할 수 없습니다." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "2단계 인증을 비활성화 할 수 없습니다." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "2단계 인증을 활성화하지 않으면 복구 코드를 생성할 수 없습니다." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "이메일 주소를 인증하기 전까지는 2단계 인증을 활성화할 수 없습니다." #: mfa/adapter.py:141 msgid "Master key" msgstr "마스터 키" #: mfa/adapter.py:143 msgid "Backup key" msgstr "벡업 키" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "키 번호. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "복구 코드" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP 인증" #: mfa/models.py:26 msgid "WebAuthn" msgstr "웹인증" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "인증 코드" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "비밀번호 없음" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "비밀번호 없는 작업을 활성화하면 이 키만 사용하여 로그인할 수 있지만, 생체 인" "식이나 PIN 보호와 같은 추가 요구 사항이 적용됩니다." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "해당 이메일을 사용중인 계정이 이미 존재합니다. 해당 계정으로 로그인 후에 %s " "계정으로 연결하세요." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "올비르지 않은 토큰" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "당신의 계정에 비밀번호가 설정되어있지 않습니다." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "당신의 계정에는 인증된 이메일이 없습니다." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "마지막 남은 소셜 계정은 연결해제 할수 없습니다." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "해당 소셜 계정이 이미 다른 계정에 연결되어 있습니다." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "소셜 계정" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "제공자" #: socialaccount/models.py:52 msgid "provider ID" msgstr "제공자 ID" #: socialaccount/models.py:56 msgid "name" msgstr "이름" #: socialaccount/models.py:58 msgid "client id" msgstr "클라이언트 아이디" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "앱 아이디 또는 컨슈머 아이디" #: socialaccount/models.py:63 msgid "secret key" msgstr "비밀 키" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API 비밀 키, 클라이언트 비밀 키, 또는 컨슈머 비밀 키" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "키" #: socialaccount/models.py:81 msgid "social application" msgstr "소셜 어플리케이션" #: socialaccount/models.py:82 msgid "social applications" msgstr "소셜 어플리케이션" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "최종 로그인" #: socialaccount/models.py:120 msgid "date joined" msgstr "가입 날짜" #: socialaccount/models.py:121 msgid "extra data" msgstr "추가 정보" #: socialaccount/models.py:125 msgid "social account" msgstr "소셜 계정" #: socialaccount/models.py:126 msgid "social accounts" msgstr "소셜 계정" #: socialaccount/models.py:160 msgid "token" msgstr "토큰" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) 또는 access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "시크릿 토큰" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) 또는 refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "만료일" #: socialaccount/models.py:174 msgid "social application token" msgstr "소셜 어플리케이션 토큰" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "소셜 어플리케이션 토큰" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "올바르지 않은 프로필 데이터" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "로그인" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "취소" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "\"%s\".로 부터 요청 토큰을 받는 도중 잘못된 응답을 받았습니다. 응답은 %s였습" "니다." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "\"%s\".로 부터 access 토큰을 받는 도중 잘못된 응답을 받았습니다." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "\"%s\".을(를) 위한 request 토큰이 없습니다." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "\"%s\".을(를) 위한 access 토큰이 없습니다." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\".에 접근하기 위한 권한이 없습니다." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "\"%s\".로 부터 request 토큰을 받는 도중 잘못된 응답을 받았습니다." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "계정 비활성" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "해당 계정은 비활성화된 상태입니다." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "접근 확인" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "계정을 보호하려면 다시 인증하세요." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "대체 옵션" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "이메일 확인" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "인증 코드 입력:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "%(email_link)s로 코드를 보냈습니다. 코드가 곧만료되므로 즉시 입력하세요." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "확인" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "로그인" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "로그인 코드 입력" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "이메일 계정" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "다음 이메일 주소들이 당신의 계정에 등록되어 있습니다." #: templates/account/email.html:25 msgid "Verified" msgstr "인증완료" #: templates/account/email.html:29 msgid "Unverified" msgstr "인증대기" #: templates/account/email.html:34 msgid "Primary" msgstr "주" #: templates/account/email.html:44 msgid "Make Primary" msgstr "주 이메일로 지정" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "인증 재전송" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "제거" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "이메일 주소 추가" #: templates/account/email.html:70 msgid "Add Email" msgstr "이메일 추가" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "정말로 선택하신 이메일을 제거하시겠습니까?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "귀하 또는 다른 사람이 다음 이메일 주소를 사용하여 계정을 등록하려고 시도했기" "에 이 이메일을 받으셨습니다:\n" "\n" "%(email)s\n" "\n" "하지만 이 이메일 주소를 사용하는 계정이 이미 존재합니다. 혹시 이 사실을 잊으" "셨다면, 비밀번호 찾기 절차를 통해 계정을 복구해 주세요:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "계정이 이미 존재합니다" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "안녕하세요 %(site_name)s입니다!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "%(site_name)s 서비스를 이용해 주셔서 감사합니다!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "귀하의 계정에 다음과 같은 변경이 이루어졌기 때문에 이 메일을 받으셨습니다:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "이 변경 사항을 인지하지 못하셨다면 즉시 적절한 보안 조치를 취해주시기 바랍니" "다. 귀하의 계정 변경 출처는 다음과 같습니다:\n" "\n" "- IP 주소: %(ip)s\n" "- 브라우저: %(user_agent)s\n" "- 날짜: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "귀하의 이메일이 %(from_email)s에서 %(to_email)s(으)로 변경되었습니다." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "이메일 변경됨" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "이메일이 확인 되었습니다." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "이메일 확인" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "%(user_display)s 에 대해 %(site_domain)s 으로부터 이메일을 인증이 전송되었습" "니다.\n" "\n" "%(activate_url)s 에서 인증을 완료하세요." #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "귀하의 로그인 코드는 아래에 나와 있습니다. 열린 브라우저 창에 입력해 주시기 " "바랍니다." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "이메일 주소를 확인하세요." #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "이메일 주소 %(deleted_email)s이(가) 귀하의 계정에서 삭제되었습니다." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "이메일 제거됨" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "귀하의 로그인 코드는 아래에 나와 있습니다. 열린 브라우저 창에 입력해 주시기 " "바랍니다." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "이 메일은 귀하가 이 작업을 시작하지 않았다면 안전하게 무시하셔도 됩니다." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "로그인 코드" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "비밀번호가 변경되었습니다." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "비밀번호 변경됨" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "회원님의 계정에 대한 암호 변경 요청이 접수되었습니다.\n" "패스워드 초기화를 원치 않는 경우 본 메일을 무시해 주십시요. 변경을 요청할 경" "우 아래 링크를 클릭하세요." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "잊어버린 경우를 대비하여, 회원님의 사용자 이름은 %(username)s 입니다." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "비밀번호 초기화 이메일" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "비밀번호가 초기화 되었습니다." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "비밀번호 초기화" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "비밀번호가 설정되었습니다." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "비밀번호 설정" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "귀하 또는 다른 사람이 이메일 %(email)s로 계정에 접근하려 했기 때문에 이 이메" "일을 받으셨습니다. 그러나 저희 데이터베이스에는 해당 계정의 기록이 없습니다." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "이 작업이 귀하에 의해 이루어진 것이라면, 아래 링크를 사용하여 계정을 등록할 " "수 있습니다." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "알 수 없는 계정" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "이메일 계정" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "현재 이메일" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "변경 중" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "귀하의 이메일 주소는 아직 검증 중입니다." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "변경 취소" #: templates/account/email_change.html:49 msgid "Change to" msgstr "변경" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "이메일 변경" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "이메일 확인" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "%(email)s이 사용자 %(user_display)s의 이메일" "이 맞는지 확인해 주세요." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "%(email)s은 다른 계정에서 이미 확인되었기 때문에 확인할 수 없습니다." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "이 이메일 확인 링크는 만료되었거나 유효하지 않습니다. 새로운 이메일 확인 요청을 해주세요." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "계정이 없다면 %(link)s회원가입%(end_link)s을 진행하세요." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "패스키로 로그인" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "로그인 코드 메일로 받기" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "로그아웃" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "정말로 로그아웃 하시겠습니까?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "주 이메일은 제거할 수 없습니다 (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "%(email)s 으로 확인 메일이 전송되었습니다." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s 을 확인하였습니다." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s 을 제거하였습니다." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s 으로 로그인 되었습니다." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "로그아웃 되었습니다." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "로그인 코드가 %(email)s로 이메일로 발송되었습니다." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "비밀번호가 성공적으로 변경되었습니다." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "비밀번호가 성공적으로 설정되었습니다." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "주 이메일이 지정되었습니다." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "비밀번호 변경" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "비밀번호를 잊으셨나요?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "비밀번호를 잊으셨나요? 아래에 당신의 이메일을 입력하시면, 비밀번호 초기화 이" "메일을 전송해 드리겠습니다." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "비밀번호 초기화" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "비밀번호 초기화에 문제가 있으시면 저희에게 연락주세요." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "메일을 전송하였습니다. 메일을 받지 못했다면 스팸 폴더를 확인해주세요.몇 분 후" "에도 메일을 받지 못하시면 저희에게 연락주세요." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "올비르지 않은 토큰" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "비밀번호 초기화 링크가 올바르지 않습니다. 다시 비밀번호 초기화 하세요." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "비밀번호가 변경되었습니다." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "비밀번호 설정" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "패스워드 입력:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "비밀번호 없이 로그인할 수 있는 특별 코드가 포함된 이메일을 받게 됩니다." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "코드 요청" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "다른 로그인 옵션" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "회원가입" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "회원가입" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "이미 계정이 있으신가요? 바로 %(link)s로그인%(end_link)s 하세요." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "패스키로 로그인" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "회원가입" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "다른 로그인 옵션" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "회원가입 종료" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "죄송합니다. 회원가입은 현재 종료되었습니다." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "메모" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "%(user_display)s 로 이미 로그인 되어있습니다." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "경고: " #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "등록된 이메일이 없습니다. 알림, 비밀번호 초기화 등을 위해 이메일을 등록해야 " "합니다." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "이메일을 인증하세요" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "인증 메일이 전송되었습니다. 회원가입 완료를 위해 전송된 메일의 링크를 클릭하" "세요. 인증 메일을 받지 못했다면 스팸 폴더를 확인해주세요. 몇 분 후에도 메일" "이 전송되지 않으면 저희에게 연락주세요." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "해당 페이지는 계정 소유주가 맞는지\n" "확인해야합니다.\n" "이를 위해 이메일 주소 소유권을 확인해야 합니다." #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "인증 메일이 전송되었습니다. \n" "회원가입 완료를 위해 전송된 메일의 링크를 클릭하세요. 인증 메일을 받지 못했다" "면 스팸 폴더를 확인해주세요. 몇 분 후에도 메일이 전송되지 않으면 저희에게 연" "락주세요." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "메모: 이메일 변경이 가능합니" "다." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "메시지:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "메뉴:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "계정 연결" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "2단계 인증" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "세션" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "귀하의 계정은 2단계 인증으로 보호되고 있습니다. 인증 코드 입력해 주세요:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "새로운 2단계 인증 복구 코드 세트가 생성되었습니다." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "새로운 복구 코드가 생성되었습니다." #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "인증 앱이 활성화 되었습니다." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "인증 앱이 활성화 되었습니다." #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "인증 앱이 비활성화 되었습니다." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "인증 앱이 비활성화 되었습니다." #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "새로운 보안키가 추가되었습니다." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "보안키 추가됨" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "보안 키가 제거되었습니다." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "보안키 제거됨" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "인증 앱" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "인증 앱을 사용한 인증이 활성화 되었습니다." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "인증 앱이 활성화 되지 않았습니다." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "비활성화" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "활성화" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "보안키" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "보안키가 추가되지 않았습니다." #: templates/mfa/index.html:62 msgid "Manage" msgstr "관리" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "추가" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "복구 코드" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "복구 코드가 설정되지 않았습니다." #: templates/mfa/index.html:96 msgid "View" msgstr "보기" #: templates/mfa/index.html:102 msgid "Download" msgstr "다운로드" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "생성" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "새로운 복구 코드 세트가 생성되었습니다." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "보안 키가 추가 되었습니다." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "보안 키가 삭제되었습니다." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "인증 코드 입력:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "귀하의 계정을 위한 새로운 복구 코드 세트를 생성하려고 합니다." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "이 작업은 기존 코드를 무효화 합니다." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "확실하세요?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "사용되지 않은 코드" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "코드 다운로드" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "새로운 코드 생성" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "인증 앱 활성화" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "귀하의 계정을 2단계 인증으로 보호하려면 아래의 QR 코드를 인증기 앱으로 스캔하" "세요. 그런 다음, 앱에서 생성된 인증 코드를 아래에 입력하세요." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "인증 secret" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "이 secret을 저장해 두면 나중에 인증기 앱을 재설치할 때 사용할 수 있습니다." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "인증 앱 비활성화" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "인증 앱 기반 인증을 비활성화하려고 합니다. 확실하세요?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "보안키 추가" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "보안키 제거" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "정말로 보안키를 제거하시겠습니까?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "사용" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "패스키" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "보안 키" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "이 키는 패스키인지 여부를 나타내지 않습니다." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "지정되지 않음" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "%(created_at)s에 추가됨" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "%(last_used)s에 마지막으로 사용됨" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "변경" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "보안 키 변경" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "저장" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "패스키" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "생성됨" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "이 기능은 자바스크립트를 요구합니다." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "소셜 로그인 실패" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "소셜 계정을 통해 로그인 하는 도중 오류가 발생했습니다." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "다음 소셜 계정들을 통해 로그인 할 수 있습니다:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "해당 계정에 연결되어있는 소셜 계정이 없습니다." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "소셜 계정을 추가하세요." #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "%(provider)s로 부터 소셜 계정이 귀하의 계정에 연결되었습니다." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "소셜 계정 연결됨." #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "%(provider)s로 부터 소셜 계정이 귀하의 계정에서 연결이 해제되었습니다." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "소셜 계정이 연결 해제됨" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "%(provider)s 계정 연결" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "%(provider)s에서 제공하는 소셜 계정을 연결하려 합니다." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "%(provider)s을 통한 로그인" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "소셜 %(provider)s의 계정을 사용해 로그인을 진행하려 합니다." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "계속" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "로그인 취소됨" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "기존 계정중 하나를 사용한 로그인을 취소하였습니다. 실수로 인한 경우, 로그인을 진행해 주세요." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "소셜 계정이 연결되었습니다." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "소셜 계정 연결이 해제되었습니다." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "%(provider_name)s 의 계정을 이용하여 %(site_name)s 으로 로그인하려 합니다.\n" "마지막으로 다음 폼을 작성해주세요:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "또는 소셜을 사용하세요." #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "모든 다른 세션에서 로그아웃되었습니다." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "시작 시작" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP 주소" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "브라우저" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "마지막으로 본 시간" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "현재" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "다른 세션에서 로그아웃" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "사용자 세션" #: usersessions/models.py:92 msgid "session key" msgstr "세션 키" #~ msgid "Account Connection" #~ msgstr "계정 연결" django-allauth-65.0.2/allauth/locale/ky/000077500000000000000000000000001467545753200200345ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ky/LC_MESSAGES/000077500000000000000000000000001467545753200216215ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ky/LC_MESSAGES/django.po000066400000000000000000001621651467545753200234360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:44+0200\n" "Last-Translator: Murat Jumashev \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" "Plural-Forms: nplurals=1; plural=0;\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Бул эсеп учурда активдүү эмес." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Негизги эмейл даректи алып салуу мүмкүн эмес (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Бул эмейл дарек ушул эсеп менен буга чейин туташтырылган." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Сиз берген эмейл дарек жана/же купуя туура эмес." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Мындай эмейл менен катталган колдонуучу бар." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Учурдагы купуяңызды жазыңыз." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Азыркы купуя" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Токен туура эмес" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Купуяны жаңыртуу токени туура эмес." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Сиздин эсебиңизде дурусталган эмейл даректер жок." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Өтө көп жолу кирүү аракеттери жасалды. Кайрадан аракеттениңиз." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Эмейл дарек эч бир колдонуучу эсебине байланган эмес" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Негизги эмейл дарегиңиз дурусталышы керек." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Бул атты колдонуу мүмкүн эмес. Башкасын тандаңыз." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Сиз берген колдонуучу аты жана/же купуя туура эмес." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Купуяңызды унуттуңузбу?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "токендин жашыруун ачкычы" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "жашыруун ачкыч" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Негизги эмейл дарегиңиз дурусталышы керек." #: account/apps.py:11 msgid "Accounts" msgstr "Эсептер" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Сиз ошол эле купуяны кайрадан териңиз." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Купуя" #: account/forms.py:93 msgid "Remember Me" msgstr "Мени эстеп кал" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Эмейл дарек" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Эмейл" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Колдонуучу аты" #: account/forms.py:123 msgid "Username or email" msgstr "Колдонуучу аты же эмейл" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Логин" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Купуяңызды унуттуңузбу?" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "Эмейл (милдеттүү эмес)" #: account/forms.py:303 #, fuzzy #| msgid "email confirmation" msgid "Email address confirmation" msgstr "эмейл ырастоо" #: account/forms.py:311 msgid "Email (optional)" msgstr "Эмейл (милдеттүү эмес)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Сиз ошол эле купуяны кайрадан териңиз." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Купуя (дагы бир жолу)" #: account/forms.py:554 msgid "Current Password" msgstr "Азыркы купуя" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Жаңы купуя" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Жаңы купуя (кайрадан)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "колдонуучу" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "эмейл дарек" #: account/models.py:34 msgid "verified" msgstr "дурусталган" #: account/models.py:35 msgid "primary" msgstr "негизги" #: account/models.py:41 msgid "email addresses" msgstr "эмейл даректер" #: account/models.py:150 msgid "created" msgstr "түзүлгөн" #: account/models.py:151 msgid "sent" msgstr "жөнөтүлгөн" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "ачкыч" #: account/models.py:157 msgid "email confirmation" msgstr "эмейл ырастоо" #: account/models.py:158 msgid "email confirmations" msgstr "эмейл ырастоолор" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "жашыруун ачкыч" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Купуя" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Бул эмейл менен башка эсеп катталган. Ошол эсеп аркылуу кирип, %s эсебиңизди " "туташтырып алыңыз." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Токен туура эмес" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Сиздин эсебиңизде купуя орнотулган эмес." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Сиздин эсебиңизде дурусталган эмейл даректер жок." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Эсебиңизге кийинки үчүнчү тарап эсептердин бирин колдонуп кирсеңиз болот:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Бул социалдык эсеп башка эсепке туташтырылган." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Социалдык эсептер" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "провайдер" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "провайдер" #: socialaccount/models.py:56 msgid "name" msgstr "аты" #: socialaccount/models.py:58 msgid "client id" msgstr "кардар id'си" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Колдонмо ID'си, же керектөөчү ачкычы" #: socialaccount/models.py:63 msgid "secret key" msgstr "жашыруун ачкыч" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API, кардар же керектөөчүнүн жашыруун ачкычы" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Ачкыч" #: socialaccount/models.py:81 msgid "social application" msgstr "социалдык колдонмо" #: socialaccount/models.py:82 msgid "social applications" msgstr "социалдык колдонмолор" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "акыркы кириши" #: socialaccount/models.py:120 msgid "date joined" msgstr "кошулган күнү" #: socialaccount/models.py:121 msgid "extra data" msgstr "кошумча маалымат" #: socialaccount/models.py:125 msgid "social account" msgstr "социалдык эсеп" #: socialaccount/models.py:126 msgid "social accounts" msgstr "социалдык эсептер" #: socialaccount/models.py:160 msgid "token" msgstr "токен" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) же жетки токени (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "токендин жашыруун ачкычы" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) же жаңыртуу токени (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "мөөнөтү аяктайт" #: socialaccount/models.py:174 msgid "social application token" msgstr "социалдык колдонмо токени" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "социалдык колдонмо токендери" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Логин" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "\"%s\" тарабынан сурам токенин алууда туура эмес жооп келди." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "\"%s\" тарабынан жетки токенин алууда туура эмес жооп келди." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "\"%s\" үчүн сурам токени сакталган жок." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "\"%s\" үчүн жетки токени сакталган жок." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\" тарабындагы жеке ресурстарга жетки жок." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "\"%s\" тарабынан сурам токенин алууда туура эмес жооп келди." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Эсеп активдүү эмес" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Бул эсеп активдүү эмес." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Эмейл даректи ырастаңыз" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "эмейл ырастоо" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "токендин жашыруун ачкычы" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Ырастоо" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Кирүү" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Эмейл даректер" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Төмөнкү эмейл даректер сиздин эсебиңизге байланган:" #: templates/account/email.html:25 msgid "Verified" msgstr "Дурусталган" #: templates/account/email.html:29 msgid "Unverified" msgstr "Дурустала элек" #: templates/account/email.html:34 msgid "Primary" msgstr "Негизги" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Негизги кылуу" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Дурустоо катын кайрадан жиберүү" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Алып салуу" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Эмейл дарек кошуу" #: templates/account/email.html:70 msgid "Add Email" msgstr "Эмейл кошуу" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Тандалган эмейл даректи алып салууну дурустайсызбы?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "%(site_name)s сайтынан алкыш!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "%(site_name)s сайтын колдонгонуңузга алкыш!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Эмейл дарек" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Сиз %(email)s дарегин ырастадыңыз." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "эмейл ырастоо" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s at " #| "%(site_domain)s has given yours as an e-mail address to connect their " #| "account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "%(site_name)s сайтынан салам!\n" "\n" "%(user_display)s деген колдонуучу %(site_domain)s деген сайттан сиздин эмейл " "дарегиңизди өзүнүн эсебине туташтырыш үчүн жазгандыктан,\n" "сиз ушул эмейл катты алып жатасыз.\n" "\n" "Бул туура десеңиз, анда %(activate_url)s аркылуу өтүп, ырастаңыз\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Эмейл дарегиңизди ырастаңыз" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Алып салуу" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Кирүү" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Купуяңыз эми өзгөртүлдү." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Купуя (дагы бир жолу)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account at %(site_domain)s.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "%(site_name)s сайтынан салам!\n" "\n" "Сиз бул катты %(site_domain)s сайтынан кимдир бирөө эсебиңиздин купуясын " "жаңыртуу сурамын жөнөткөндүктөн алып жататсыз.\n" "Эгерде сурамды сиз жөнөтпөгөн болсоңуз, бул катка көңүл бурбай эле коюңуз. " "Купуяны жаңыртуу үчүн төмөндөгү шилтемени басыңыз." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Эстей албай жатсаңыз, сиздин колдонуучу атыңыз %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Купуяны жаңыртуу эмейли" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Купуяңыз эми өзгөртүлдү." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Купуяны жаңыртуу" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Купуяңыз эми өзгөртүлдү." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Купуяны жаңыртуу" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Эсеп" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Эмейл даректер" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Азыркы купуя" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Негизги эмейл дарегиңиз дурусталышы керек." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Эмейл" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Эмейл" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Эмейл даректи ырастаңыз" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "%(email)s деген эмейл дарек " "%(user_display)s колдонуучусуна таандык экенин ырастаңыз." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Бул социалдык эсеп башка эсепке туташтырылган." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Бул эмейлди ырастоо шилтемесинин мөөнөтү өтүп кеткен же ал туура эмес. эмейлди ырастоо сурамын кайрадан жөнөтүңүз." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Эгерде сиз эсеп түзө элек болсоңуз, анда биринчи " "%(link)sкатталыңыз%(end_link)s" #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Чыгуу" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Сиз чыгып жатканыңызды дурустайсызбы?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Негизги эмейл даректи алып салуу мүмкүн эмес (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Ырастоо эмейли %(email)s дарегине жөнөтүлдү." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Сиз %(email)s дарегин ырастадыңыз." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s дарегин алып салдык." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s аты менен ийгиликтүү кирдик." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Сиз чыгып кеттиңиз." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Купуя ийгиликтүү өзгөртүлдү." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Купуя ийгиликтүү орнотулду." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Негизги эмейл орнотулду." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Купуяны өзгөртүү" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Купуяңызды унуттуңузбу?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Купуяңызды унуттуңузбу? Эмейл дарегиңизди төмөндө жазсаңыз, биз сизге кат " "жөнөтүп, аны жаңыртканга жардам беребиз." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Купуямды жаңырт" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Купуяны жаңыртууда суроолор пайда болсо, бизге кайрылыңыз." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Биз сизге кат жөнөттүк, дурустоо үчүн.\n" "Ичинде берилген шилтемени басыңыз. Эгерде\n" "кат бир нече мүнөттө келбей калса, бизге кайрылыңыз." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Токен туура эмес" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Купуя жаңыртуу шилтемеси туура эмес экен, ал мурун колдонулса керек. Купуяны жаңыртуу сурамын кайрадан " "жөнөтүңүз." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Купуяңыз эми өзгөртүлдү." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Купуя орнотуу" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Купуяңызды унуттуңузбу?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Катталуу" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Катталуу" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Эсебиңиз барбы? Анда %(link)sкириңиз%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Катталуу" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Катталуу жабык" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Кечирим сурайбых, бирок учурда катталуу жабык." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Эскертүү" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "сиз %(user_display)s катары кирип турасыз." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Эскертүү:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Сизде азыр бир дагы эмейл катталган эмес. Билдирүүлөрдү алуу, купуяны " "жаңыртуу ж.б. үчүн каттап коюңуз." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Эмейл дарегиңизди дурустап бериңиз" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Биз эмейлиңизди дурустоо үчүн кат жөнөттүк. Ошондо берилген шилтеме аркылуу " "өтүп, каттоодон өтүңүз. Кат бир нече мүнөттө келбесе, бизге кайрылыңыз." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Сайттын бул бөлүгүнө өтүш үчүн сиз чын эле сиз айткан \n" "адам экендиңизди такташыбыз керек. Ал үчүн эмейл\n" "дарек сизге таандык экенин дурусташыңыз керек." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Биз сизге кат жөнөттүк, дурустоо үчүн.\n" "Ичинде берилген шилтемени басыңыз. Эгерде\n" "кат бир нече мүнөттө келбей калса, бизге кайрылыңыз." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Эскертүү: эмейл дарегиңизди дагы деле өзгөртсөңүз болот." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Эсеп байланыштары" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "токендин жашыруун ачкычы" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "токендин жашыруун ачкычы" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Сиз %(email)s дарегин ырастадыңыз." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "токендин жашыруун ачкычы" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "токендин жашыруун ачкычы" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "жашыруун ачкыч" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "жашыруун ачкыч" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Сиз чыгып жатканыңызды дурустайсызбы?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "жашыруун ачкыч" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Дурустала элек" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "жашыруун ачкыч" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Азыркы купуя" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "түзүлгөн" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Социалдык тармак аркылуу кирүү ийгиликсиз" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Социалдык тармак эсебиңиз аркылуу кирүүдө ката кетти." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Эсебиңизге кийинки үчүнчү тарап эсептердин бирин колдонуп кирсеңиз болот:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Азырынча эсебиңизге социалдык тармак эсептер байланган эмес." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "3-тарап эсеп кошуу" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "3-тарап эсеп кошуу" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "3-тарап эсеп кошуу" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Кирүү токтотулду" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Эсептериңизин бирөөсүн колдонуп сайтыбызга кирүүдөн баш тарттыңыз. Аны " "байкабастан кылып алсаңыз, кирүүнү улантсаңыз " "болот." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Социалдык эсеп туташтырылды." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Социалдык эсеп ажыратылды." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Сиз азыр %(provider_name)s эсебиңизди колдонуп, %(site_name)s\n" "сайтына кирейин деп турасыз. Акыркы кадам катары кийинки калыпты\n" "толтуруп коюңузду суранабыз :" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Эмейл даректер" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Азыркы купуя" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Эсеп байланыштары" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Купуя жок дегенде {0} белгиден турушу керек." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "%(site_name)s сайтынан салам!\n" #~ "\n" #~ "Сиз бул катты %(site_domain)s сайтынан кимдир бирөө эсебиңиздин купуясын " #~ "жаңыртуу сурамын жөнөткөндүктөн алып жататсыз.\n" #~ "Эгерде сурамды сиз жөнөтпөгөн болсоңуз, бул катка көңүл бурбай эле " #~ "коюңуз. Купуяны жаңыртуу үчүн төмөндөгү шилтемени басыңыз." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Төмөнкү эмейл даректер сиздин эсебиңизге байланган:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Эмейл даректи ырастаңыз" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Тышкаркы кызматтарда катталган\n" #~ "эсебиңиз аркылуу кириңиз. Же, %(site_name)s \n" #~ "сайтына %(link)sкатталып%(end_link)s\n" #~ "\"төмөн жактан кириңиз:" #~ msgid "or" #~ msgstr "же" #~ msgid "change password" #~ msgstr "купуяны өзгөртүү" #~ msgid "OpenID Sign In" #~ msgstr "OpenID менен кирүү" #~ msgid "This email address is already associated with another account." #~ msgstr "Бул эмейл дарек башка бир эсеп менен буга чейин туташтырылган." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Биз сизге кат жөнөттүк. Бир нече мүнөттүн ичинде келбей калса бизге " #~ "кайрылыңыз." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Сиз берген логин жана/же купуя туура эмес." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Колдонуучу аттары тамгалардан, сандардан жана @/./+/-/_ белгилеринен гана " #~ "тура алат." django-allauth-65.0.2/allauth/locale/lt/000077500000000000000000000000001467545753200200305ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/lt/LC_MESSAGES/000077500000000000000000000000001467545753200216155ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/lt/LC_MESSAGES/django.po000066400000000000000000001465471467545753200234400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:02+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < " "11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? " "1 : n % 1 != 0 ? 2: 3);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Šiuo metu ši paskyra yra neaktyvi." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Negalite pašalinti pagrindinio el. pašto." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Šis el. pašto adresas jau susietas su šia paskyra." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Pateiktas el. pašto adresas ir/arba slaptažodis yra neteisingi." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Šiuo el. pašto adresu jau yra užsiregistravęs kitas naudotojas." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Prašome įvesti esamą jūsų slaptažodį." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Neteisingas kodas." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Neteisingas slaptažodis." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Neteisingas arba pasenęs raktas." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Neteisingas slaptažodžio atstatymo atpažinimo ženklas." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Negalima pridėti daugiau nei %d el. pašto adresų." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Per daug nepavykusių prisijungimo bandymų. Bandykite vėliau." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "El. pašto adresas nėra susietas su jokia naudotojo paskyra" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Pirminis el. pašto adresas turi būti patvirtintas." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Šis naudotojo vardas negalimas. Prašome pasirinkti kitą naudotojo vardą." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Pateiktas naudotojo vardas ir/arba slaptažodis yra neteisingi." #: account/adapter.py:741 msgid "Use your password" msgstr "Naudokite slaptažodį" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Naudokite autentifikacijos programą arba kodą" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Naudokite saugumo raktą" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Pažymėti pasirinktus el. pašto adresus, kaip patvirtintus" #: account/apps.py:11 msgid "Accounts" msgstr "Paskyros" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Turite įvesti tą patį slaptažodį kiekvieną kartą." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Slaptažodis" #: account/forms.py:93 msgid "Remember Me" msgstr "Prisimink mane" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "El. pašto adresas" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "El. paštas" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Naudotojo vardas" #: account/forms.py:123 msgid "Username or email" msgstr "Naudotojo vardas arba el. paštas" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Prisijungimo vardas" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Pamiršote slaptažodį?" #: account/forms.py:299 msgid "Email (again)" msgstr "El. paštas (pakartoti)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "El. pašto patvirtinimas" #: account/forms.py:311 msgid "Email (optional)" msgstr "El. paštas (neprivalomas)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Turite įvesti tą patį el. pašto adresą kiekvieną kartą." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Slaptažodis (pakartoti)" #: account/forms.py:554 msgid "Current Password" msgstr "Esamas slaptažodis" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Naujas slaptažodis" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Naujas slaptažodis (pakartoti)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kodas" #: account/models.py:26 msgid "user" msgstr "naudotojas" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "el. pašto adresas" #: account/models.py:34 msgid "verified" msgstr "patvirtintas" #: account/models.py:35 msgid "primary" msgstr "pirminis" #: account/models.py:41 msgid "email addresses" msgstr "el. pašto adresai" #: account/models.py:150 msgid "created" msgstr "sukurtas" #: account/models.py:151 msgid "sent" msgstr "išsiųstas" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "raktas" #: account/models.py:157 msgid "email confirmation" msgstr "el. pašto patvirtinimas" #: account/models.py:158 msgid "email confirmations" msgstr "el. pašto patvirtinimai" #: headless/apps.py:7 msgid "Headless" msgstr "Begalvis" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Jūs negalite pridėti el. pašto adreso į dviguba autentifikacija saugomą " "paskyrą." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Jūs negalite deaktyvuoti dvigubos autentifikacijos." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Jūs negalite generuoti atstatymo kodų be įjungtos dvigubos autentifikacijos." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Jūs negalite aktyvuoti dvigubos autentifikacijos kol nepatvirtinsite savo " "el. pašto." #: mfa/adapter.py:141 msgid "Master key" msgstr "Pagrindinis raktas" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Atsarginis raktas" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Rakto nr. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Be Slaptažodžio" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Paskyra su šiuo el. pašto adresu jau egzistuoja. Prašome pirmiausia " "prisijungti prie tos paskyros ir tada prijunkite %s paskyrą." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Klaidinga atpažinimo žymė" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Jūsų paskyra neturi nustatyto slaptažodžio." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Jūsų paskyra neturi patvirtinto el. pašto adreso." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Negalite atjungti paskutinės trečiosios šalies paskyros." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Trečiosios šalies paskyra jau yra prijungta prie kitos paskyros." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Socialinės paskyros" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "tiekėjas" #: socialaccount/models.py:52 msgid "provider ID" msgstr "tiekėjo ID" #: socialaccount/models.py:56 msgid "name" msgstr "pavadinimas" #: socialaccount/models.py:58 msgid "client id" msgstr "kliento id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID arba consumer key" #: socialaccount/models.py:63 msgid "secret key" msgstr "secret key" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API secret, client secret, arba consumer secret" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Raktas" #: socialaccount/models.py:81 msgid "social application" msgstr "socialinė programėlė" #: socialaccount/models.py:82 msgid "social applications" msgstr "socialinės programėlės" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "paskutinis prisijungimas" #: socialaccount/models.py:120 msgid "date joined" msgstr "registracijos data" #: socialaccount/models.py:121 msgid "extra data" msgstr "papildomi duomenys" #: socialaccount/models.py:125 msgid "social account" msgstr "socialinė paskyra" #: socialaccount/models.py:126 msgid "social accounts" msgstr "socialinės paskyros" #: socialaccount/models.py:160 msgid "token" msgstr "atpažinimo ženklas" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) arba prieigos atpažinimo ženklas (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token secret" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" "\"oauth_token_secret\" (OAuth1) arba atnaujintas atpažinimo ženklas (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "galiojimas" #: socialaccount/models.py:174 msgid "social application token" msgstr "socialinės programėlės atpažinimo ženklas" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "socialinės programėlės atpažinimo ženklai" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Neteisingi profilio duomenys" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Prisijungti" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Atšaukti" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Klaidingas atsakymas gaunant užklausos atpažinimo ženklą iš \"%s\". " "Atsakymas buvo: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Klaidingas atsakymas gaunant prieigos atpažinimo ženklą iš \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Nėra užklausos atpažinimo žymės šiam \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Nėra prieigos atpažinimo žymės šiam \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Nėra prieigos prie privataus resurso iš \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Klaidingas atsakymas gaunant užklausos atpažinimo ženklą iš \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Paskyra neaktyvi" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Ši paskyra neaktyvi." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Patvirtinkite Prieigą" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Prašome dar kartą autentifikuotis, kad apsaugotumete savo paskyrą." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Kiti pasirinkimai" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "El. Pašto Patvirtinimas" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Įrašykite Teisingą Patvirtinimo Kodą" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Į %(email_link)s išsiuntėme kodą. Kodo galiojimas greitai pasibaigs, tas " "įrašykite jį kuo greičiau." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Patvirtinti" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Prisijungti" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Įrašykite Prisijungimo Kodą" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "El. pašto adresai" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Šie el. pašto adresas yra susieti su jūsų paskyra:" #: templates/account/email.html:25 msgid "Verified" msgstr "Patvirtintas" #: templates/account/email.html:29 msgid "Unverified" msgstr "Nepatvirtintas" #: templates/account/email.html:34 msgid "Primary" msgstr "Pirminis" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Padaryti pirminiu" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Pakartotinai siųsti patvirtinimą" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Šalinti" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Pridėti el. pašto adresą" #: templates/account/email.html:70 msgid "Add Email" msgstr "Pridėti el. paštą" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Ar tikrai norite ištrinti pasirinktą el. pašto adresą?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Jūs gaunate šį laišką, nes kažkas bandė prisiregistruoti\n" " naudojantis :\n" "\n" "%(email)s\n" "\n" "Paskyra su šiuo el. pašto adresu egzistuoja. Jei užmiršote\n" " apie tai, prašome naudotis užmiršto slaptažodžio procedūra, kad " "atstatytumėte\n" "jūsų paskyrą:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Pakyra Jau Egzistuoja" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Ačiū nuo %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Ačiū, kad naudojate %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Jūs gaunate šį laišką, nes šie pakitimai buvo padaryti jūsų paskyrai:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Jei neatpažįstate šių pakitimų, imkitės saugumo užtikrinimo veiksmų. " "Paskyros pakitimai buvo įvykdyti iš:\n" "\n" "- IP adreses: %(ip)s\n" "- Naršyklė: %(user_agent)s\n" "- Data: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" "Jūsų el. pašto adresas buvo pakeistas iš %(from_email)s į %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "El. Paštas Pasikeitė" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Jūsų el. paštas patvirtintas." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "El. Pašto Patvirtinimas" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Jūs gavote šį laišką, kadangi naudotojas %(user_display)s iš %(site_domain)s " "prijungė šį el. pašto adresą prie savo paskyros." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Jūsų el. pašto patvirtinimo kodas yra nurodytas žemiau. Prašome įvesti jį į " "atidarytos naršklės langą." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Patvirtinkite, kad tai yra teisinga, eidami į %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Prašome patvirtinti savo el. pašto adresą" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "El. pašto adresas %(deleted_email)s buvo pašalintas iš jūsų paskyros." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "El. Paštas Pašalintas" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Jūsų el. pašto patvirtinimo kodas yra nurodytas žemiau. Prašome įvesti jį į " "atidarytos naršyklės langą." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Šis laiškas gali būti ignoruojamas jei šio veiksmo neiniciavote." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Prisijungimo Kodas" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Jūsų slaptažodis pakeistas." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Slaptažodis Pakeistas" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Jūs gavote šį laišką, kadangi jūs arba kažkas kitas pateikė slaptažodžio " "keitimo užklausą paskyrai susietai su šiuo el. pašto adresu iš " "%(site_domain)s.\n" "Jei jūs neteikėte slaptažodžio keitimo užklausos, galite ignoruoti šį " "laišką. Kad pakeistumėte savo slaptažodį sekite žemiau esančią nuorodą." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Primename, kad jūsų naudotojo vardas yra %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Slaptažodžio keitimo el. paštas" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Jūsų slaptažodis atstatytas." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Slaptažodžio atstatymas" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Jūsų slaptažodis nustatytas." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Slaptažodžio Nustatymas" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Jūs gaunate šį laišką, nes kažkas bandė prisijungti prie paskyros su el. " "pašto adresu %(email)s, tačiau tokios paskyros duombazėje nėra." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "Jei tai buvote jūs, registruotis galite sekdami nuorodą apačioje." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Nežinoma Paskyra" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "El. Pašto Adresas" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Esamas el. pašto adresas" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Keičiama į" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Jūsų el. pašto adresas dar vis laukia patvirtinimo." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Atšaukti Keitimą" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Pakeista į" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Keisti El. Paštas Adresą" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Patvirtinkite el. pašto adresą" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Prašome patvirtinti, kad %(email)s yra " "%(user_display)s el. pašto adresas." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "%(email)s nepatvirtintas, nes šį el. paštą jau patvirtino kita paskyra." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Šios el. pašto patvirtinimo nuorodos galiojimas baigėsi arba nuoroda yra " "klaidinga. Prašome pateikti naują el. pašto " "patvirtinimo užklausimą." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Jei dar nesusikūrėte paskyros, tuomet prašome pirmiausia " "%(link)ssusikurti%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Prisijunkite su prieigos raktu" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Atsiųsti prisijungimo kodą" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Atsijungti" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Ar tikrai norite atsijungti?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Negalite ištrinti pirminio (%(email)s) el. pašto adreso." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Patvirtinimo laiškas išsiųstas adresu %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s patvirtintas." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s el. pašto adresas ištrintas." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Sėkmingai prisijungėte kaip %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Atsijungėte." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Prisijungimo kodas buvo nusiųstas į %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Slaptažodis sėkmingai pakeistas." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Slaptažodis pakeistas sėkmingai." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Pirminis el. pašto adresas pakeistas sėkmingai." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Keisti slaptažodį" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Pamiršote slaptažodį?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Pamiršote slaptažodį? Įveskite savo el. pašto adresą žemiau ir mes išsiūsime " "jums laišką, kurio pagalba galėsite pasikeisti slaptažodį." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Atstatyti mano slaptažodį" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Prašome susisiekti su mumis jei negalite atstatyti slaptažodžio." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Išsiuntėme jums patvirtinimo laišką. Prašome sekite nuorodą pateiktą laiške. " "Susisiekite su mumis jei negausite laiško per kelias minutes." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Klaidinga atpažinimo žymė" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Slaptažodžio atstatymo nuoroda klaidinga, taip gali būti dėl to, kad nuoroda " "jau buvo kartą panaudota. Prašome pakartoti slaptažodžio atstatymą." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Jūsų slaptažodis pakeistas." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Nustatyti slaptažodį" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Įrašykite slaptažodį:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "Gausite laišką su specialiu kodu prisijungimui be slaptažodžio." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Prašyti Kodo" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Kiti prisijungimo pasirinkimai" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registracija" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registruotis" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Jau turite paskyrą? Prašome %(link)sprisijungti%(end_link)s." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "Prisijunkite su prieigos raktu" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Registruotis" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Kiti prisijungimo pasirinkimai" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registracija uždaryta" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Atsiprašome, tačiau registracija šiuo metu yra uždaryta." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Pastaba" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Jūs jau esate prisijungęs, kaip %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Įspėjimas:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Šiuo metu jūs neturite nustatyto el. pašto adreso. Rekomenduojame pridėti " "el. pašto adresą, kad gautumėte pranešimus, galėtumėte atstatyti slaptažodį " "ir pan." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Patvirtinkite savo el. pašto adresą" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Išsiuntėme jums laišką patvirtinimui. Sekite laiške pateiktą nuorodą, kad " "užbaigtumėte registraciją. Jei nematote laiško pagrindiniame skyriuje, " "patikrinkite šlamšto skyrių. Prašome susisiekti su mumis, jei laiško " "negavote per kelias minutes." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Šioje svetainės vietoje privalome gauti iš jūsų patvirtinimą,\n" "kad jūs tikrai esate tas asmuo, kaip teigiate. Dėl šios priežasties\n" "prašome patvirtinti el. pašto adreso nuosavybę. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Išsiuntėme jums patvirtinimo laišką.\n" "Prašome sekite nuorodą pateiktą laiške. Jei laiško nematote, patikrinkite " "šlamšto skyrių. Susisiekite su mumis\n" "jei negausite laiško per kelias minutes." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Pastaba: vis dar galite pakeisti " "savo el. pašto adresą." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Žinutės:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Meniu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Paskyros ryšiai" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Dviejų Faktorių Autentifikacija" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sesijos" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Autentifikacijos Aplikacija Aktyvuota" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Autentifikacijos Aplikacija Deaktyvuota" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Saugumo raktas buvo pašalintas." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Įveskite autentifikatoriaus kodą:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Autentifikatoriaus paslaptis" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Pridėti Saugumo Raktą" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Pašalinti Saugumo Raktą" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Ar tikrai norite pašalinti šį saugumo raktą?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Saugumo raktas" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Nenurodytas" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Keisti Saugumo Raktą" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Esamas slaptažodis" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "sukurtas" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Trečiosios Šalies Prisijungimo Klaida" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Įvyko nenumatyta klaida bandant prisijungti trčiosios šalies paskyra." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Galite prisijungti prie savo paskyros naudodami vieną iš galimų trečios " "šalies paskyrų:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "" "Šiuo metu jūs neturite nei vienos prijungtos trečiosios šalies paskyros." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Pridėti Trečiosios Šalies paskyrą" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "Trečiosios šalies paskyra iš %(provider)s buvo prijungta prie jūsų paskyros." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Trečiosios Šalies Paskyra Prijungta" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "Trečiosios šalies paskyra iš %(provider)s buvo atjungta nuo jūsų paskyros." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Trečiosios Šalies Paskyra Atjungta" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Prijungti %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Jūs tuojaus prijungsite naują trečiosios šalies paskyrą iš %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Prisijungkite Su %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Jūs tuojaus prisijungsite naudojantis trečiosios šalies paskyra iš " "%(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Tęsti" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Prisijungimas atšauktas" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Nusprendėte atšaukti prisijungimą naudojant vieną iš esamų paskyrų. Jei tai " "buvo klaida, prašome pakartoti prisijungimą." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Trečiosios šalies paskyra buvo prijungta." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Trečiosios šalies paskyra buvo atjungta." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Jūs beveik prisijungėte prie %(site_name)s naudodami %(provider_name)s\n" "paskyrą. Liko paskutinis žingsnis, užpildyti sekančią formą:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Arba naudokite trečiąją šalį" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Atsijungta nuo visų kitų sesijų." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Pradėta" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP Adresas" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Naršyklė" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Paskutinį kartą matyta" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Esamas" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Atjungti Kitas Sesijas" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Vartotojo Sesijos" #: usersessions/models.py:92 msgid "session key" msgstr "sesijos raktas" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Paskyros ryšiai" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Slaptažodis turi būti sudarytas mažiausiai iš {0} simbolių." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Su jumis sveikinasi %(site_name)s\n" #~ "\n" #~ "Jūs gavote šį laišką, kadangi jūs arba kažkas kitas pateikė slaptažodžio " #~ "keitimo užklausą paskyrai susietai su šiuo el. pašto adresu iš " #~ "%(site_domain)s.\n" #~ "Jei jūs neteikėte slaptažodžio keitimo užklausos, galite ignoruoti šį " #~ "laišką. Kad pakeistumėte savo slaptažodį sekite žemiau esančią nuorodą." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Šie el. pašto adresas yra susieti su jūsų paskyra:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Patvirtinkite el. pašto adresą" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Prašome prisijungti viena\n" #~ "iš jūsų turimų trečios šalies paskyrų. Arba, susikurkite\n" #~ "naują %(site_name)s paskyrą ir prisijunkite žemiau:" #~ msgid "or" #~ msgstr "arba" #~ msgid "change password" #~ msgstr "keisti slaptažodį" #~ msgid "OpenID Sign In" #~ msgstr "OpenID prisijungimas" #~ msgid "This email address is already associated with another account." #~ msgstr "Šis el. pašto adresas jau susietas su kita paskyra." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Išsiuntėme jums laišką. Prašome susisiekti su mums jei per kelias minutes " #~ "negausite laiško." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Pateiktas prisijungimo vardas ir/arba slaptažodis yra neteisingi." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "Naudotojo vardui galima naudoti tik raides, skaičius ir @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Šis naudotojo vardas jau užimtas. Prašome pasirinkti kitą." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Prisijungti" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Jūs patvirtinote, kad %(email)s yra " #~ "%(user_display)s naudotojo el. pašto adresas." django-allauth-65.0.2/allauth/locale/lv/000077500000000000000000000000001467545753200200325ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/lv/LC_MESSAGES/000077500000000000000000000000001467545753200216175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/lv/LC_MESSAGES/django.po000066400000000000000000001505771467545753200234400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:51+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " "2);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Šis konts šobrīd ir neaktīvs." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Jūs nevarat noņemt savu primāro e-pasta adresi (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Šī e-pasta adrese jau ir piesaistīta šim kontam." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Nepareizs e-pasts un/vai parole." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Lietotājs ar šādu e-pasta adresi jau ir reģistrēts." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Lūdzu ievadiet jūsu šobrīdējo paroli." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Šobrīdējā parole" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Nederīgs marķieris" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Paroles atjaunošanas marķieris bija nederīgs." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Jūsu kontam nav apstiprinātas e-pasta adreses." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Pārāk daudz neveiksmīgi pieslēgšanās mēģinājumi. Mēģiniet vēlreiz vēlāk." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "E-pasta adrese nav piesaistīta nevienam lietotāja kontam" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Jūsu primārajai e-pasta adresei jābūt apstiprinātai." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Lietotājvārds nevar tikt izmantots. Lūdzu izvēlietis citu lietotājvārdu." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Nepareizs lietotāja vārds un/vai parole." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Aizmirsāt paroli?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "token secret" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "secret key" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Jūsu primārajai e-pasta adresei jābūt apstiprinātai." #: account/apps.py:11 msgid "Accounts" msgstr "Konti" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Katru reizi jums ir jāievada tā pati parole." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Parole" #: account/forms.py:93 msgid "Remember Me" msgstr "Atcerēties mani" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-pasta adrese" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-pasts" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Lietotājvārds" #: account/forms.py:123 msgid "Username or email" msgstr "Lietotājvārds vai e-pasts" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Ieiet" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Aizmirsāt paroli?" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "E-pasts (izvēles)" #: account/forms.py:303 #, fuzzy #| msgid "email confirmation" msgid "Email address confirmation" msgstr "e-pasta apstiprinājums" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-pasts (izvēles)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Katru reizi jums ir jāievada tā pati parole." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Parole (vēlreiz)" #: account/forms.py:554 msgid "Current Password" msgstr "Šobrīdējā parole" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Jaunā parole" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Jaunā parole (vēlreiz)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "lietotājs" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-pasta adrese" #: account/models.py:34 msgid "verified" msgstr "apstiprināts" #: account/models.py:35 msgid "primary" msgstr "primārā" #: account/models.py:41 msgid "email addresses" msgstr "e-pasta adreses" #: account/models.py:150 msgid "created" msgstr "izveidots" #: account/models.py:151 msgid "sent" msgstr "nosūtīts" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "atslēga" #: account/models.py:157 msgid "email confirmation" msgstr "e-pasta apstiprinājums" #: account/models.py:158 msgid "email confirmations" msgstr "e-pasta apstiprinājumi" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "secret key" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Parole" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Jau eksistē konts ar šo e-pasta adresi. Lūdzu sākumā ieejiet tajā kontā, tad " "pievienojiet %s kontu." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Nederīgs marķieris" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Jūsu kontam nav uzstādīta parole." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Jūsu kontam nav apstiprinātas e-pasta adreses." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Jūs varat ieiet jūsu kontā izmantojot jebkuru no sekojošiem trešo pušu " "kontiem:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Sociālais konts jau ir piesaistīts citam kontam." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sociālie konti" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "sniedzējs" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "sniedzējs" #: socialaccount/models.py:56 msgid "name" msgstr "vārds" #: socialaccount/models.py:58 msgid "client id" msgstr "klienta id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID, vai consumer key" #: socialaccount/models.py:63 msgid "secret key" msgstr "secret key" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API secret, client secret, vai consumer secret" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Key" #: socialaccount/models.py:81 msgid "social application" msgstr "sociālā aplikācija" #: socialaccount/models.py:82 msgid "social applications" msgstr "sociālās aplikācijas" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "pēdējā pieslēgšanās" #: socialaccount/models.py:120 msgid "date joined" msgstr "reģistrācijas datums" #: socialaccount/models.py:121 msgid "extra data" msgstr "papildus informācija" #: socialaccount/models.py:125 msgid "social account" msgstr "sociālais konts" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sociālie konti" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) vai piekļūt marķierim (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token secret" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) vai atjaunot marķieri (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "beidzas" #: socialaccount/models.py:174 msgid "social application token" msgstr "sociālās aplikācijas marķieris" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "sociālās aplikācijas marķieri" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Ieiet" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Nederīga atbilde iegūstot pieprasījuma marķieri no \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Nederīga atbilde iegūstot pieejas marķieri no \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Netika saglabāts pieprasījuma marķieris priekš \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Netika saglabāts pieejas marķieris priekš \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Nav pieejas privātam resursam \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Nederīga atbilde iegūstot pieprasījuma marķieri no \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Neaktīvs konts" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Šis konts ir neaktīvs." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Apstipriniet e-pasta adresi" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "e-pasta apstiprinājums" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "token secret" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Apstiprināt" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Ieiet" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-pasta adreses" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Sekojošas e-pasta adreses ir piesaistītas jūsu kontam:" #: templates/account/email.html:25 msgid "Verified" msgstr "Apstiprināta" #: templates/account/email.html:29 msgid "Unverified" msgstr "Neapstiprināta" #: templates/account/email.html:34 msgid "Primary" msgstr "Primārā" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Iestatīt kā primāro" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Pārsūtīt apstiprināšanu" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Noņemt" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Pievienot e-pasta adresi" #: templates/account/email.html:70 msgid "Add Email" msgstr "Pievienot e-pastu" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Vai jūs tiešām vēlaties noņemt izvēlēto e-pasta adresi?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "Visu labu vēlot, %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Paldies, ka izmantojat %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "E-pasta adrese" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Jūs esat apstiprinājis %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "e-pasta apstiprinājums" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s at " #| "%(site_domain)s has given yours as an e-mail address to connect their " #| "account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Sveiciens no %(site_name)s!\n" "\n" "Jūs saņemat šo e-pasta vēstuli tāpēc, ka lietotājs %(user_display)s lapā " "%(site_domain)s ir iesniedzis šo e-pasta adresi, lai tā tiktu sasaistīta ar " "viņa kontu.\n" "\n" "Lai apstiprinātu, ka viss ir parezi, ejiet uz %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Lūdzu apstipriniet savu e-pasta adresi" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Noņemt" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Ieiet" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Jūsu parole ir nomainīta." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Parole (vēlreiz)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account at %(site_domain)s.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Sveiciens no %(site_name)s!\n" "\n" "Jūs saņemat šo e-pasta vēstuli tāpēc, ka jūs vai kāds cits ir pieprasījis " "paroles atjaunošanu jūsu kontam lapā %(site_domain)s.\n" "Jūs varat droši ignorēt šo e-pasta vēstuli, ja jūs nepieprasījat paroles " "atjaunošanu. Spiedied uz linka zemāk, lai atjaunotu jūsu paroli." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Gadījumā ja jūs aizmirsāt, tad jūsu lietotājvārds ir %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Paroles atjaunošanas e-pasts" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Jūsu parole ir nomainīta." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Atjaunot paroli" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Jūsu parole ir nomainīta." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Atjaunot paroli" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Konts" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "E-pasta adreses" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Šobrīdējā parole" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Jūsu primārajai e-pasta adresei jābūt apstiprinātai." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-pasts" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-pasts" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Apstipriniet e-pasta adresi" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Lūdzu apstipriniet ka %(email)s e-pasta " "adrese pieder lietotājam %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Sociālais konts jau ir piesaistīts citam kontam." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Šī e-pasta apstiprināšanas saitei ir beidzies derīguma termiņš vai tas ir " "nederīgs. Lūdzu pieprasiet jaunu e-pasta " "apstiprināšanas linku." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ja jūs vēl neesat izveidojuši kontu, tad lūdzu " "%(link)spiereģistrējaties%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Iziet" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Vai jūs tiešām vēlaties iziet?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Jūs nevarat noņemt savu primāro e-pasta adresi (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Apstiprinājuma e-pasts nosūtīts uz %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Jūs esat apstiprinājis %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Noņemta e-pasta adrese %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Veiksmīgi iegājuši kā %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Jūs esat izgājuši." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Parole veiksmīgi nomainīta." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Parole veiksmīgi uzstādīta." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primārā e-pasta adrese uzstādīta." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Mainīt paroli" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Aizmirsāt paroli?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Aizmirsāt savu paroli? Ievadiet zemāk savu e-pasta adresi, un mēs jums " "nosūtīsim e-pasta vēstuli, lai atjaunotu to." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Atjaunot manu paroli" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Lūdzu sazinieties ar mums, ja jums ir kādas problēmas atjaunojot to." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Mēs esam jums nosūtījuši e-pastu\n" "apstiprināšanai. Lūdzu klikšķiniet uz saites šajā e-pastā. Lūdzu\n" "sazinieties ar mums, ja dažu minūšu laikā nesaņemat vēstuli." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Nederīgs marķieris" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Paroles atjaunošanas links ir nederīgs, iespējams, tāpēc ka tas jau ir " "izmantots. Lūdzu pieprasiet jaunu paroles " "atjaunošanu." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Jūsu parole ir nomainīta." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Uzstādīt paroli" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Aizmirsāt paroli?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Reģistrēties" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Reģistrēties" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Jau ir konts? Tad lūdzu %(link)sspiedied šeit%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Reģistrēties" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Reģistrācija slēgta" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Mēs atvainojamies, bet reģistrācija šobrīd ir slēgta." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Piezīme" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "jūs jau esat iegājuši kā %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Brīdinājums:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Jums pašlaik nav izveidota neviena e-pasta adrese. Jums patiešām vajadzētu " "pievienot e-pasta adresi, lai jūs varētu saņemt paziņojumus, atiestatīt savu " "paroli utt." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Apstipriniet savu e-pasta adresi" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Jums ir nosūtīts apstiprinājuma e-pasts. Sekojiet saitei, lai pabeigu " "reģistrācijas procesu. Lūdzu sazinieties ar mums, ja dažu minūšu laikā " "nesaņemat vēstuli." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Šī lapas daļa mums nosaka pārbaudīt, ka\n" "jūs esat tas, kas jūs apgalvojat esam. Šim mērķim, mēs pieprasām, lai jūs\n" "apstipriniet, jūsu e-pasta adreses piederību. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Mēs esam jums nosūtījuši e-pastu\n" "apstiprināšanai. Lūdzu klikšķiniet uz saites šajā e-pastā. Lūdzu\n" "sazinieties ar mums, ja dažu minūšu laikā nesaņemat vēstuli." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Piezīme: jūs vēljoprojām varat nomainīt jūsu e-pasta adresi." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Konta savienojumi" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "token secret" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "token secret" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Jūs esat apstiprinājis %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "token secret" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "token secret" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Vai jūs tiešām vēlaties iziet?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Neapstiprināta" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "secret key" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Šobrīdējā parole" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "izveidots" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Sociālā tīkla ieiešanas kļūda" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Notikusi kļūme, mēģinot ieiet ar jūsu sociālo kontu." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Jūs varat ieiet jūsu kontā izmantojot jebkuru no sekojošiem trešo pušu " "kontiem:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Jūsu kontam šobrīd nav piesaistīts neviens sociālais konts." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Pievienot trešās puses kontu" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Pievienot trešās puses kontu" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Pievienot trešās puses kontu" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Ieiešana pārtraukta" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Jūs nolēmāt pārtraukt ieiešanu mūsu lapa izmantojot vienu no jūsu kontiem. " "Ja šī ir kļūda, lūdzu dodaties uz ieiet." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Sociālais konts ir piesaistīts." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Sociālais konts ir atvienots." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Jūs izmantosiet savu %(provider_name)s kontu, lai ieietu\n" "%(site_name)s. Kā pēdējo soli, lūdzu aizpildiet sekojošo formu:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "E-pasta adreses" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Šobrīdējā parole" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Konta savienojumi" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Parolei jābūt vismaz {0} simbolus garai." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Sveiciens no %(site_name)s!\n" #~ "\n" #~ "Jūs saņemat šo e-pasta vēstuli tāpēc, ka jūs vai kāds cits ir pieprasījis " #~ "paroles atjaunošanu jūsu kontam lapā %(site_domain)s.\n" #~ "Jūs varat droši ignorēt šo e-pasta vēstuli, ja jūs nepieprasījat paroles " #~ "atjaunošanu. Spiedied uz linka zemāk, lai atjaunotu jūsu paroli." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Sekojošas e-pasta adreses ir piesaistītas jūsu kontam:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Apstipriniet e-pasta adresi" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Lūdzu ieejiet iekšā ar vienu\n" #~ "no jūsu eksistējošiem trešās puses kontiem. Vai reģistrējieties\n" #~ "%(site_name)s kontam un ieejiet zemāk:" #~ msgid "or" #~ msgstr "vai" #~ msgid "change password" #~ msgstr "Nomainīt paroli" #~ msgid "OpenID Sign In" #~ msgstr "Ieiet ar OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Šī e-pasta adrese jau ir piesaistīta citam kontam." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Mēs jums nosūtījām e-pasta vēstuli. Lūdzu sazinieties ar mums, ja dažu " #~ "minūšu laikā nesaņemat vēstuli." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Nepareiza pieteikšanās informācija un/vai parole." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "Lietotājvārds var saturēt tikai burtus, ciparus un @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Šis lietotājvārds jau ir aizņemts. Lūdzu izvēlaties citu." #~ msgid "Shopify Sign In" #~ msgstr "Ieiet ar Shopify" django-allauth-65.0.2/allauth/locale/mn/000077500000000000000000000000001467545753200200235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/mn/LC_MESSAGES/000077500000000000000000000000001467545753200216105ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/mn/LC_MESSAGES/django.po000066400000000000000000001606271467545753200234260ustar00rootroot00000000000000# Mongolian Translation # Copyright (C) 2021 # This file is distributed under the same license as the PACKAGE package. # Bilgutei Erdenebayar , 2021. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:32+0200\n" "Last-Translator: Bilgutei Erdenebayar \n" "Language-Team: Mongolian \n" "Language: mn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Энэ бүртгэл одоогоор идэвхгүй байна." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Та үндсэн имэйл хаяг (%(email)s)-г устгах боломжгүй." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Энэ имэйл хаяг энэ бүртгэлтэй холбогдсон байна." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Таны оруулсан имэйл хаяг болон/эсвэл нууц үг буруу байна." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Өөр хэрэглэгч энэ имэйл хаягаар бүртгүүлсэн байна." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Одоогийн нууц үгээ оруулна уу." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Одоогын Нууц Үг" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Муу токен" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Нууц үг шинэчлэх токен буруу байна." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Та %d-с илүү имэйл хаяг нэмэх боломжгүй." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Хэт олон амжилтгүй нэвтрэх оролдлого. Дараа дахин оролдоорой." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Имэйл хаяг ямар ч хэрэглэгчийн бүртгэлтэй холбогдоогүй" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Таны үндсэн имэйл хаягийг баталгаажуулсан байх ёстой." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Хэрэглэгчийн нэрийг ашиглах боломжгүй. Өөр нэр сонгоно уу." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Таны оруулсан имэйл хаяг болон/эсвэл нууц үг буруу байна." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Нууц Үг Мартсан?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "токен нууц" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "нууц түлхүүр" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Таны үндсэн имэйл хаягийг баталгаажуулсан байх ёстой." #: account/apps.py:11 msgid "Accounts" msgstr "Бүртгэлүүд" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Та өмнө оруулсантай ижил нууц үг оруулах ёстой." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Нууц үг" #: account/forms.py:93 msgid "Remember Me" msgstr "Намайг Санах" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Имэйл хаяг" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Хэрэглэгчийн нэр" #: account/forms.py:123 msgid "Username or email" msgstr "Хэрэглэгчийн нэр эсвэл имэйл" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Нэвтрэх" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Нууц Үг Мартсан?" #: account/forms.py:299 msgid "Email (again)" msgstr "Имэйл (дахин)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Имэйл хаягийн баталгаажуулалт" #: account/forms.py:311 msgid "Email (optional)" msgstr "Имэйл (заавал биш)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Та өмнө оруулсантай ижил имэйл бичих ёстой." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Нууц үг (дахин)" #: account/forms.py:554 msgid "Current Password" msgstr "Одоогын Нууц Үг" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Шинэ Нууц Үг" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Шинэ Нууц Үг (дахин)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "хэрэглэгч" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "имэйл хаяг" #: account/models.py:34 msgid "verified" msgstr "баталгаажуулсан" #: account/models.py:35 msgid "primary" msgstr "үндсэн" #: account/models.py:41 msgid "email addresses" msgstr "имэйл хаягууд" #: account/models.py:150 msgid "created" msgstr "үүсгэсэн" #: account/models.py:151 msgid "sent" msgstr "илгээсэн" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "түлхүүр" #: account/models.py:157 msgid "email confirmation" msgstr "имэйл баталгаажуулалт" #: account/models.py:158 msgid "email confirmations" msgstr "имэйл баталгаажуулалт" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "нууц түлхүүр" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Нууц үг" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Энэ имэйл хаягтай бүртгэл системд байна. Түүгээр нэвтэрнэ үүэхлээд бүртгэл, " "дараа нь %s бүртгэлээ холбоно уу" #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Муу токен" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Таны бүртгэлд нууц үг тохируулаагүй байна." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Таны бүртгэлд баталгаажсан имэйл хаяг алга." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Та дараах гуравдагч этгээдийн аль нэг бүртгэлийг ашиглан өөрийн бүртгэлд " "нэвтэрч болно." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Сошиал хаяг аль хэдийн өөр бүртгэлд холбогдсон байна." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Сошиал Бүртгэлүүд" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "үйлчилгээ үзүүлэгч" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "үйлчилгээ үзүүлэгч" #: socialaccount/models.py:56 msgid "name" msgstr "нэр" #: socialaccount/models.py:58 msgid "client id" msgstr "клиент ID" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Апп ID эсвэл хэрэглэгчийн түлхүүр" #: socialaccount/models.py:63 msgid "secret key" msgstr "нууц түлхүүр" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API нууц, клиент нууц эсвэл хэрэглэгчийн нууц" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Түлхүүр" #: socialaccount/models.py:81 msgid "social application" msgstr "сошиал апп" #: socialaccount/models.py:82 msgid "social applications" msgstr "сошиал апп-ууд" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "сүүлд нэвтэрсэн" #: socialaccount/models.py:120 msgid "date joined" msgstr "бүртгүүлсэн огноо" #: socialaccount/models.py:121 msgid "extra data" msgstr "нэмэлт өгөгдөл" #: socialaccount/models.py:125 msgid "social account" msgstr "сошиал хаяг" #: socialaccount/models.py:126 msgid "social accounts" msgstr "сошиал хаягууд" #: socialaccount/models.py:160 msgid "token" msgstr "токен" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) эсвэл нэвтрэх токен (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "токен нууц" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) эсвэл шинэчлэх токен (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "дуусах хугацаа" #: socialaccount/models.py:174 msgid "social application token" msgstr "сошиал апп токен" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "сошиал апп токенууд" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Буруу профайлын өгөгдөл" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Нэвтрэх" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "\"%s\"-с request токен авах үед буруу хариу." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "\"%s\"-с access токен авах үед буруу хариу." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "\"%s\"-д request токен хадгалагдаагүй." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "\"%s\"-д access токен хадгалагдаагүй." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\" дээрх private resource-д хандах боломжгүй." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "\"%s\"-с request токен авах үед буруу хариу." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Бүртгэл идэвхгүй" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Энэ бүртгэл идэвхгүй байна." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Имэйл Хаяг Баталгаажуулах" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "имэйл баталгаажуулалт" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "токен нууц" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Баталгаажуулах" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Нэвтрэх" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Имэйл Хаягууд" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Дараах и-мэйл хаягууд таны бүртгэлтэй холбоотой байна:" #: templates/account/email.html:25 msgid "Verified" msgstr "Баталгаажсан" #: templates/account/email.html:29 msgid "Unverified" msgstr "Баталгаажаагүй" #: templates/account/email.html:34 msgid "Primary" msgstr "Үндсэн" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Үндсэн Болгох" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Баталгаажуулалтыг дахин илгээх" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Устгах" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Имэйл хаяг нэмэх" #: templates/account/email.html:70 msgid "Add Email" msgstr "Имэйл нэмэх" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Та үнэхээр сонгосон имэйл хаягаа устгахыг хүсэж байна уу?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "%(site_name)s-с мэнд хүргэж байна!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "%(site_name)s-г хэрэглэсэнд баярлалаа!%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email (again)" msgid "Email Changed" msgstr "Имэйл (дахин)" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Та %(email)s-г баталгаажууллаа." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "имэйл баталгаажуулалт" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "%(user_display)s хэрэглэгч %(site_domain)s дээр бүртгэл бүртгүүлэхийн " "тулданы и-мэйл хаягийг өгсөн тул та энэ имэйлийг хүлээн авч байна.\n" "\n" "Үүнийг зөв эсэхийг баталгаажуулахын тулд %(activate_url)s руу очно уу" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Имэйл хаягаа баталгаажуулна уу" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Устгах" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Нэвтрэх" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Таны нууц үг одоо өөрчлөгдсөн байна." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Нууц үг (дахин)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Та эсвэл өөр хэн нэгэн таны бүртгэлтэй нууц үгийг хүссэн тул нэ " "имэйлийгхүлээн авч байна.\n" "Хэрэв та нууц үг шинэчлэх хүсэлт гаргаагүй бол энэ имэйлийг устгаж болно." "Нууц үгээ шинэчлэх бол доорх холбоос дээр дарна уу." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Хэрэв та мартсан бол таны хэрэглэгчийн нэр %(username)s байна." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Нууц Үг Шинэчлэх Имэйл" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Таны нууц үг одоо өөрчлөгдсөн байна." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Нууц үг шинэчлэх" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Таны нууц үг одоо өөрчлөгдсөн байна." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Нууц үг шинэчлэх" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "Бүртгэлүүд" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Имэйл Хаягууд" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Одоогын Нууц Үг" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Таны үндсэн имэйл хаягийг баталгаажуулсан байх ёстой." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Имэйл хаяг" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Имэйл хаяг" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Имэйл Хаяг Баталгаажуулах" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "%(email)s нь %(user_display)s " "хэрэглэгчийнимайл хаяг гэдгийг баталгаажуулна уу." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Сошиал хаяг аль хэдийн өөр бүртгэлд холбогдсон байна." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Энэ и-мэйл баталгаажуулах холбоосын хугацаа дууссан эсвэл хүчингүй байна.шинэ имэйлээр баталгаажуулах хүсэлт гаргана уу." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Хэрэв та бүртгэл үүсгээгүй байгаа бол эхлээд %(link)sбүртгүүлнэ " "үү%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Гарах" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Та холболт салгахдаа итгэлтэй байна уу?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Та үндсэн имэйл хаяг (%(email)s)-г устгах боломжгүй." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "%(email)s-руу баталгаажуулах имэйл илгээсэн." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Та %(email)s-г баталгаажууллаа." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s и-мэйл хаягийг устгасан." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s нэрээр амжилттай нэвтэрлээ." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Та холболт салгалаа." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Нууц үг амжилттай өөрчлөгдлөө." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Нууц үгийг амжилттай тохирууллаа." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Үндсэн имэйл хаягийг тохируулсан." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Нууц үг солих" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Нууц Үг Мартсан?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Нууц үгээ мартсан уу? Доор бүртгэлтэй и-мэйл хаягаа оруулж нууц үг шинэчлэх " "имэйлээр нууц үгээ сэргээнэ уу." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Нууц Үг Шинэчлэх" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Нууц үгээ шинэчлэхэд асуудал гарвал бидэнтэй холбогдоно уу." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Бид танд баталгаажуулах и-мэйл илгээсэн.\n" "Энэ цахим шуудангийн доторх холбоос дээр дарна уу. Хэдэн минутын\n" "дотор хүлээж авахгүй бол бидэнтэй холбоо барина уу." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Муу токен" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Нууц үг шинэчлэх холбоос хүчингүй байсан, үүнийг аль хэдийн ашигласан байж " "магадгүй. шинэ нууц үг шинэчлэх хүсэлт " "гаргана уу." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Таны нууц үг одоо өөрчлөгдсөн байна." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Нууц үг тохируулах" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Нууц Үг Мартсан?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Бүртгүүлэх" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Бүртгүүлэх" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "Бүртгэлтэй юу? Тэгвэл бүртгэлтэй хаягаар %(link)sнэвтрэнэ үү%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Бүртгүүлэх" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Бүртгэл хаалттай" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Уучлаарай, бүртгэл одоогоор хаалттай байна." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Анхаарна уу" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "Та аль хэдийн %(user_display)s нэрээр нэвтэрсэн байна." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Анхааруулга:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Танд одоогоор тохируулсан имэйл хаяг байхгүй байна. Та имэйл хаяг нэмэх " "хэрэгтэйингэснээр та мэдэгдэл хүлээн авах, нууц үгээ шинэчлэх г.м боломжтой " "болно." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Имэйл хаягаа баталгаажуулна уу" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Бид танд баталгаажуулах и-мэйл илгээсэн. Бүртгүүлэх үйл явцыг дуусгахын тулд " "өгөгдсөн холбоосыг дагана уу. Хэдэн минутын дотор хүлээж авахгүй бол " "бидэнтэй холбоо барина уу." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Сайтын энэ хэсэг нь таныг өөрийгөө мөн болохыг\n" "баталгаажуулахыг биднээс шаарддаг. Энэ зорилгоор бид таныг цахим\n" "шуудангийн хаягаа эзэмшиж буй эсэхийг баталгаажуулахыг шаардаж байна." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Бид танд баталгаажуулах и-мэйл илгээсэн.\n" "Энэ цахим шуудангийн доторх холбоос дээр дарна уу. Хэдэн минутын\n" "дотор хүлээж авахгүй бол бидэнтэй холбоо барина уу." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Санамж: та мэйл хаягаа өөрчлөхболомжтой хэвээр байна." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Бүртгэлийн холболтууд" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "токен нууц" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "токен нууц" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Та %(email)s-г баталгаажууллаа." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "токен нууц" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "токен нууц" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "нууц түлхүүр" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "нууц түлхүүр" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Та холболт салгахдаа итгэлтэй байна уу?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "нууц түлхүүр" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Баталгаажаагүй" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "нууц түлхүүр" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Одоогын Нууц Үг" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "үүсгэсэн" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Сошиал-р нэвтрэхэд алдаа гарлаа" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Таны сошиал бүртгэлээр нэвтрэхийг оролдох үед алдаа гарлаа." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Та дараах гуравдагч этгээдийн аль нэг бүртгэлийг ашиглан өөрийн бүртгэлд " "нэвтэрч болно." #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Танд одоогоор энэ бүртгэлд холбогдсон сошиал бүртгэл байхгүй байна." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Гуравдагч этгээдийн бүртгэл нэмэх" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Гуравдагч этгээдийн бүртгэл нэмэх" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Гуравдагч этгээдийн бүртгэл нэмэх" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Нэвтрэлт цуцлагдсан" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Та одоо байгаа бүртгэлийнхээ аль нэгийг ашиглан манай сайтад нэвтрэхээ " "цуцлахаар шийдсэн. Хэрэв энэ нь алдаа байсан бол нэвтэрнэ үү." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Сошиал хаяг холбогдсон байна." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Сошиал хаягыг салгасан." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Та %(site_name)s руу нэвтрэхийн тулд %(provider_name)s бүртгэлээ\n" "ашиглах гэж байна. Эцсийн алхам болгон дараах маягтыг бөглөнө үү:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Имэйл Хаягууд" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Одоогын Нууц Үг" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Бүртгэлийн холболтууд" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Нууц үг хамгийн багадаа {0} тэмдэгттэй байх ёстой." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Та эсвэл өөр хэн нэгэн таны бүртгэлтэй нууц үгийг хүссэн тул нэ " #~ "имэйлийгхүлээн авч байна.\n" #~ "Хэрэв та нууц үг шинэчлэх хүсэлт гаргаагүй бол энэ имэйлийг устгаж болно." #~ "Нууц үгээ шинэчлэх бол доорх холбоос дээр дарна уу." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Дараах и-мэйл хаягууд таны бүртгэлтэй холбоотой байна:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Имэйл Хаяг Баталгаажуулах" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Одоо байгаа гуравдагч\n" #~ "этгээдийн бүртгэлийн аль нэгээр нэвтэрнэ үү. Эсвэл %(site_name)s бүртгэлд " #~ "%(link)sбүртгүүлж%(end_link)sдоор нэвтэрнэ үү:" #~ msgid "or" #~ msgstr "эсвэл" #~ msgid "change password" #~ msgstr "нууц үг солих" #~ msgid "OpenID Sign In" #~ msgstr "OpenID-р Нэвтрэх" #~ msgid "This email address is already associated with another account." #~ msgstr "Энэ имэйл хаяг өөр бүртгэлтэй холбогдсон байна." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Бид танд имэйл илгээсэн. Хэдхэн минутын дотор хүлээж авахгүй бол бидэнтэй " #~ "холбоо барина уу." django-allauth-65.0.2/allauth/locale/nb/000077500000000000000000000000001467545753200200105ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/nb/LC_MESSAGES/000077500000000000000000000000001467545753200215755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/nb/LC_MESSAGES/django.po000066400000000000000000001461211467545753200234040ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:52+0200\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.4-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Denne kontoen er inaktiv." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Du kan ikke fjerne den primær e-postadressen (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Denne e-postadressen er allerede tilknyttet denne kontoen." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "E-postadressen og/eller passordet du oppgav er feil." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "En bruker med denne e-postadressen er allerede registrert." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Vennligst skriv inn ditt passord." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Nåværende passord" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Ugyldig token" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Nøkkelen for passordgjenopprettelse var ugyldig." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Din konto har ingen verifisert e-postadresse." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "For mange innloggingsforsøk. Vennligst prøv igjen senere." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "E-postadressen er ikke tilknyttet noen brukerkonto" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Din primære e-postadresse må være verifisert." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Brukernavnet kan ikke benyttes. Vennligst velg et annet brukernavn." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Brukernavnet og/eller passordet du oppgav er feil." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Glemt passord?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "hemmelig nøkkel" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "hemmelig nøkkel" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Din primære e-postadresse må være verifisert." #: account/apps.py:11 msgid "Accounts" msgstr "Kontoer" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Du må skrive det samme passordet hver gang." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Passord" #: account/forms.py:93 msgid "Remember Me" msgstr "Husk meg" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-postadresse" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-post" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Brukernavn" #: account/forms.py:123 msgid "Username or email" msgstr "Brukernavn eller e-post" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Logg inn" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Glemt passord?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-post (igjen)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Bekreftelse av e-postadresse" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-post (valgfritt)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Du må skrive inn samme e-post hver gang." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Passord (igjen)" #: account/forms.py:554 msgid "Current Password" msgstr "Nåværende passord" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nytt passord" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nytt passord (igjen)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kode" #: account/models.py:26 msgid "user" msgstr "bruker" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-postadresse" #: account/models.py:34 msgid "verified" msgstr "verifisert" #: account/models.py:35 msgid "primary" msgstr "primær" #: account/models.py:41 msgid "email addresses" msgstr "e-postadresser" #: account/models.py:150 msgid "created" msgstr "opprettet" #: account/models.py:151 msgid "sent" msgstr "sendt" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "nøkkel" #: account/models.py:157 msgid "email confirmation" msgstr "e-postbekreftelse" #: account/models.py:158 msgid "email confirmations" msgstr "e-postbekreftelser" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "hemmelig nøkkel" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Gjenopprettingskoder" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Passord" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "En konto med denne e-postadressen eksisterer fra før. Vennligst logg inn på " "den kontoen først for så å koble til din %s konto." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Ugyldig token" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Kontoen din har ikke noe passord." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Din konto har ingen verifisert e-postadresse." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Du kan logge inn på din konto ved å bruke en av følgende tredjeparts kontoer:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Tredjepartskonten er allerede tilknytet til en annen konto." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sosiale kontoer" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "tilbyder" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "tilbyder" #: socialaccount/models.py:56 msgid "name" msgstr "navn" #: socialaccount/models.py:58 msgid "client id" msgstr "klient-ID" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App-ID eller konsumentnøkkel" #: socialaccount/models.py:63 msgid "secret key" msgstr "hemmelig nøkkel" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API-nøkkel, klient-nøkkel eller konsumentnøkkel" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Nøkkel" #: socialaccount/models.py:81 msgid "social application" msgstr "sosial applikasjon" #: socialaccount/models.py:82 msgid "social applications" msgstr "sosiale applikasjoner" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "siste innlogging" #: socialaccount/models.py:120 msgid "date joined" msgstr "ble med dato" #: socialaccount/models.py:121 msgid "extra data" msgstr "ekstra data" #: socialaccount/models.py:125 msgid "social account" msgstr "sosialkonto" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sosialkontoer" #: socialaccount/models.py:160 msgid "token" msgstr "nøkkel" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) eller aksess token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "hemmelig nøkkel" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) eller oppdateringsnøkkel (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "utgår den" #: socialaccount/models.py:174 msgid "social application token" msgstr "sosial applikasjonsnøkkel" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "sosial applikasjonsnøkler" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Ugyldig profildata" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Logg inn" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Ugyldig respons ved henting av forespørselsnøkkel fra \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Ugyldig respons ved henting av tilgangsnøkkel fra \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Ingen etterspørselsnøkler lagret for \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Ingen tilgangsnøkler lagret for \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Ingen tilgang til private ressurser på \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Ugyldig respons ved henting av forespørselsnøkkel fra \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Inaktiv konto" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Denne kontoen er inaktiv." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Bekreft e-postadresse" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "e-postbekreftelse" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "hemmelig nøkkel" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Bekreft" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Logg inn" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-postadresser" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Følgende e-postadresser er assosiert med din konto:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verifisert" #: templates/account/email.html:29 msgid "Unverified" msgstr "Ikke verifisert" #: templates/account/email.html:34 msgid "Primary" msgstr "Primær" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Sett som primær" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Send verifikasjon på nytt" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Fjern" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Legg til e-postadresse" #: templates/account/email.html:70 msgid "Add Email" msgstr "Legg til e-post" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Er du sikker på at du vil fjerne valgt e-postadresse?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "Takk fra %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Takk for at du bruker %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "E-postadresse" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Du har bekreftet %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "e-postbekreftelse" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s has given " #| "yours as an e-mail address to connect their account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Hei fra %(site_name)s!\n" "\n" "Du mottar denne e-postadressen fordi %(user_display)s har gitt din e-" "postkonto for å koble til sin brukerkonto.\n" "\n" "For å bekrefte at dette stemmer, gå til %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Vennligst bekreft din e-postadresse" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Fjern" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Logg inn" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Ditt passord er endret." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Passord (igjen)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Hei fra %(site_name)s!\n" "\n" "Du mottar denne e-postadressen fordi du eller noen andre har etterspurt et " "passord for din brukerkonto.\n" "Meldingen kan trygt ignoreres om du ikke foretok denne etterspørselen. Klikk " "på linken nedenfor for å gjennopprette ditt passord." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "I tilfelle du har glemt det: Brukernavnet ditt er %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-post for gjenopprettelse av passord" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Ditt passord er endret." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Passordgjenopprettelse" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Ditt passord er endret." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Passordgjenopprettelse" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Konto" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "E-postadresser" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Nåværende passord" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Din primære e-postadresse må være verifisert." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-post" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-post" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Bekreft e-postadresse" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Vennligst bekreft at %(email)s er en e-" "postadresse for bruker %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Tredjepartskonten er allerede tilknytet til en annen konto." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Denne e-postbekreftelseslinken er utgått eller ugyldig. Vennligst etterspør en ny e-postbekreftelseslink." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Om du enda ikke har laget en konto, vennligst %(link)sregistrer " "deg%(end_link)s først." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Logg ut" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Er du sikker at du ønsker å logge ut?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Du kan ikke fjerne den primær e-postadressen (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Bekreftelsese-post er sendt til %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Du har bekreftet %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Fjern e-postadressen %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Logget inn som %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Du har logget ut." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Passordet er endret." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Passordet er satt." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primær e-postadresse er satt." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Endre Passord" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Glemt passord?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Glemt ditt passord? Skriv inn din e-postadresse nedenfor, så sender vi deg " "en e-post for å lage et nytt." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Gjenopprett mitt passord" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Vennligst kontakt oss om du har problemer med passordgjenopprettelsen." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Vi har send en e-post til deg for\n" "verifikasjon. Vennligst klikk på linken i e-posten. Vennligst kontakt oss om " "du ikke mottar den innen et par minutter." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Ugyldig token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Passordgjenopprettelseslinken er ugyldig – muligens fordi den allerede er " "brukt. Vennligst etterspør en ny " "passordgjennopprettelse." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Ditt passord er endret." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Sett passord" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Glemt passord?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registrer deg" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registrer deg" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Har du allerede en konto? Vennligst %(link)slogg inn%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Registrer deg" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registrering stengt" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Beklager, men registrering er for tiden stengt." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Notat" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "du er allerede logget inn som %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Advarsel:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Du har for tiden ingen e-postadresse satt opp. Du burde legge til en e-" "postadresse slik at du kan motta varsler, gjennoprette passord ol." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Bekreft din e-postadresse" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Vi har sendt deg en e-post for verifisering. Følg linken for å fullføre " "registreringen. Vennligst kontakt oss om du ikke har mottatt den innen et " "par minutter." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Denne delen av siden krever at du verifiserer at du er den du er. På grunn " "av dette, må du verifisere ditt eierskap av din e-postadresse. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Vi har send en e-post til deg for\n" "verifikasjon. Vennligst klikk på linken i e-posten. Vennligst kontakt oss om " "du ikke mottar den innen et par minutter." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Merk: du kan fremdeles endre din " "your e-postadresse." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Kontotilkoblinger" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "hemmelig nøkkel" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "hemmelig nøkkel" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Du har bekreftet %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "hemmelig nøkkel" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "hemmelig nøkkel" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "hemmelig nøkkel" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "hemmelig nøkkel" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Er du sikker at du ønsker å logge ut?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "hemmelig nøkkel" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Ikke verifisert" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "hemmelig nøkkel" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Nåværende passord" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "opprettet" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Innlogging ved hjelp av sosialt nettverk mislyktes" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Det skjedde en feil ved forsøket på å logge inn via din nettverkskonto." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Du kan logge inn på din konto ved å bruke en av følgende tredjeparts kontoer:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Du har for tiden ingen tredjepartskontoer tilkoblet din konto." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Legg til en tredjepartskonto" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Legg til en tredjepartskonto" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Legg til en tredjepartskonto" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Innlogging kansellert" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Du bestemt deg for å kansellere innlogging til siden ved å bruke en av dine " "eksisterende kontoer. Om dette var ved en feil, vennligst fortsett til innloggingen." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Tredjepartskontoen har blitt tilknytet." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Tredjepartskontoen er blitt frakoblet." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Du er på vei til å bruke din %(provider_name)s konto for å logge inn på\n" "%(site_name)s. Som et siste steg, vennligst fullfør følgende skjema:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "E-postadresser" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Nåværende passord" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Kontotilkoblinger" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Passordet må være minst {0} tegn." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Hei fra %(site_name)s!\n" #~ "\n" #~ "Du mottar denne e-postadressen fordi du eller noen andre har etterspurt " #~ "et passord for din brukerkonto.\n" #~ "Meldingen kan trygt ignoreres om du ikke foretok denne etterspørselen. " #~ "Klikk på linken nedenfor for å gjennopprette ditt passord." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Følgende e-postadresser er assosiert med din konto:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Bekreft e-postadresse" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Vennligst logg in med en\n" #~ "av dine eksisterende tredjeparts kontoer på %(site_name)s. Eller, registrer deg\n" #~ "og logg inn nedenfor:" #~ msgid "or" #~ msgstr "eller" #~ msgid "change password" #~ msgstr "Endre passord" #~ msgid "OpenID Sign In" #~ msgstr "OpenID-innlogging" #~ msgid "This email address is already associated with another account." #~ msgstr "Denne e-postadressen er tilknyttet en annen konto." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Vi har sendt deg en e-post. Vennligst kontakt oss om du ikke mottar den " #~ "innen et par minutter." django-allauth-65.0.2/allauth/locale/nl/000077500000000000000000000000001467545753200200225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/nl/LC_MESSAGES/000077500000000000000000000000001467545753200216075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/nl/LC_MESSAGES/django.po000066400000000000000000001514171467545753200234220ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-21 14:24+0200\n" "Last-Translator: Raymond Penners \n" "Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.4-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Dit account is niet actief" #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "You kunt je primaire e-mailadres niet verwijderen." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Dit e-mailadres is al geassocieerd met dit account." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Je e-mailadres en/of wachtwoord zijn incorrect." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Er is al een gebruiker geregistreerd met dit e-mailadres." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Geef je huidige wachtwoord op." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Ongeldige code." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Ongeldig wachtwoord." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Ongeldige of verlopen sleutel." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "De wachtwoordherstel-sleutel is niet geldig." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Je kunt niet meer dan %d e-mailadressen toevoegen." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Te veel inlogpogingen. Probeer het later nogmaals." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Dit e-mailadres is niet bij ons bekend" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Je primaire e-mailadres moet geverifieerd zijn." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Deze gebruikersnaam mag je niet gebruiken, kies een andere." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Je gebruikersnaam en/of wachtwoord zijn incorrect." #: account/adapter.py:741 msgid "Use your password" msgstr "Gebruik je wachtwoord" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Gebruik authenticator-app of code" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Gebruik een beveiligingssleutel" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Markeer de geselecteerde email addressen als geverifieerd" #: account/apps.py:11 msgid "Accounts" msgstr "Accounts" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Je moet hetzelfde wachtwoord twee keer intoetsen." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Wachtwoord" #: account/forms.py:93 msgid "Remember Me" msgstr "Onthouden" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-mailadres" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Gebruikersnaam" #: account/forms.py:123 msgid "Username or email" msgstr "Gebruikersnaam of e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Login" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Wachtwoord vergeten?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (bevestigen)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Bevestig e-mailadres" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (optioneel)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Je moet hetzelfde e-mailadres twee keer intoetsen." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Wachtwoord (bevestigen)" #: account/forms.py:554 msgid "Current Password" msgstr "Huidig wachtwoord" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nieuw wachtwoord" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nieuw wachtwoord (bevestigen)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Code" #: account/models.py:26 msgid "user" msgstr "gebruiker" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-mailadres" #: account/models.py:34 msgid "verified" msgstr "geverifieerd" #: account/models.py:35 msgid "primary" msgstr "Primair" #: account/models.py:41 msgid "email addresses" msgstr "e-mailadressen" #: account/models.py:150 msgid "created" msgstr "aangemaakt" #: account/models.py:151 msgid "sent" msgstr "verstuurd" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "sleutel" #: account/models.py:157 msgid "email confirmation" msgstr "e-mailadres bevestiging" #: account/models.py:158 msgid "email confirmations" msgstr "e-mailadres bevestigingen" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Je kunt geen e-mailadres toevoegen aan een account dat beveiligd is met twee-" "factor-authenticatie is." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Je kunt twee-factor-authenticatie niet deactiveren." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Je kunt geen herstelcodes genereren zonder dat twee-factor-authenticatie " "actief is." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Je moet eerst je e-mailadres verifiëren voordat je twee-factor-authenticatie " "kunt activeren." #: mfa/adapter.py:141 msgid "Master key" msgstr "Hoofdsleutel" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Reservesleutel" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Sleutel nr. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Herstelcodes" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP Authenticator" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Authenticator code" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Wachtwoordloos" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Door wachtwoordloos inloggen mogelijk te maken kun je je aanmelden met deze " "sleutel. Dit brengt extra vereisten met zich mee, zoals biometrische " "verificatie of PIN-bescherming." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Er bestaat al een account met dit e-mailadres. Meld je eerst aan met dit " "account, verbind daarna je %s account." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Ongeldige sleutel." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Je account heeft geen wachtwoord ingesteld." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Je account heeft geen geverifieerd e-mailadres." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Je kunt het laatste externe account niet verwijderen." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Dit externe account is al gekoppeld aan een ander account." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sociale accounts" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "provider" #: socialaccount/models.py:52 msgid "provider ID" msgstr "provider ID" #: socialaccount/models.py:56 msgid "name" msgstr "naam" #: socialaccount/models.py:58 msgid "client id" msgstr "client id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "App ID, of consumer key" #: socialaccount/models.py:63 msgid "secret key" msgstr "geheime sleutel" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API secret, client secret, of consumer secret" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Sleutel" #: socialaccount/models.py:81 msgid "social application" msgstr "social application" #: socialaccount/models.py:82 msgid "social applications" msgstr "social applications" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "laatst ingelogd" #: socialaccount/models.py:120 msgid "date joined" msgstr "datum toegetreden" #: socialaccount/models.py:121 msgid "extra data" msgstr "extra data" #: socialaccount/models.py:125 msgid "social account" msgstr "social account" #: socialaccount/models.py:126 msgid "social accounts" msgstr "social accounts" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) of toegangs-token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token geheim" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) of ververs token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "verloopt op" #: socialaccount/models.py:174 msgid "social application token" msgstr "social applicatie token" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "social applicatie tokens" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Ongeldige profiel data" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Login" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Annuleren" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Ongeldig antwoord ontvangen tijdens het ophalen van een verzoeksleutel van " "\"%s\", antwoord: \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "" "Ongeldig antwoord ontvangen tijdens het ophalen van een toegangssleutel van " "\"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Geen verzoeksleutel opgeslagen voor \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Geen toegangssleutel opgeslagen voor \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Geen toegang tot privé data bij \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "" "Ongeldig antwoord ontvangen tijdens het ophalen van een verzoeksleutel van " "\"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Account inactief" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Dit account is niet actief" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Toegang bevestigen" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Authenticeer opnieuw om de beveiliging van je account te waarborgen." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Andere opties" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "E-mailadres verificatie" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Voer de e-emailadres verificatie code in:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "We hebben een aanmeldcode verstuurd naar %(email_link)s. Deze code vervalt " "binnenkort, dus vul deze snel in." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Bevestigen" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Aanmelden" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Aanmeldcode invullen" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-mailadressen" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "De volgende e-mailadressen zijn gekoppeld aan jouw account:" #: templates/account/email.html:25 msgid "Verified" msgstr "Geverifieerd" #: templates/account/email.html:29 msgid "Unverified" msgstr "Ongeverifieerd" #: templates/account/email.html:34 msgid "Primary" msgstr "Primair" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Maak primair" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Stuur verificatie e-mail opnieuw" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Verwijder" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Voeg e-mailadres toe" #: templates/account/email.html:70 msgid "Add Email" msgstr "E-mail toevoegen" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Wil je het geselecteerde e-mailadres echt verwijderen?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Je ontvangt deze e-mail omdat jij of iemand anders geprobeerd heeft een " "account\n" "te registreren met dit e-mail adres:\n" "\n" "%(email)s\n" "\n" "Echter, er bestaat al een account met dit e-mail adres. Als je dit " "vergeten\n" "was, gebruik dan de wachtwoord vergeten procedure om de toegang tot je " "account\n" "te herstellen:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Account bestaat al" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Hallo van %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Bedankt voor het gebruiken van %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Je ontvangt deze e-mail vanwege de volgende wijziging aan je account:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Herken je deze wijziging niet? Neem dan onmiddelijk voorzorgsmaatregelen en " "beveilig je account. Deze wijzigingen komen van:\n" "\n" "- IP adres: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Datum: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Je email adres is gewijzigd van %(from_email)s naar %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E-mailadres gewijzigd" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Je e-mailadres is bevestigd." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "E-mailadres bevestiging" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Je ontvangt deze e-mail omdat gebruiker %(user_display)s van\n" "%(site_domain)s dit als e-mailadres heeft opgegeven om te koppelen\n" "aan zijn of haar account." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Hieronder staat je e-mailadres verificatiecode. Vul deze in in het browser " "venster dat nog open staat." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Om te bevestigen dat dit correct is, bezoek: %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Bevestig je e-mailadres" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "Email adres %(deleted_email)s is ontkoppeld van je account." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "E-mailadres verwijderd" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Hieronder staat je aanmeldcode. Vul deze in in het browser venster dat nog " "open staat." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Je kunt deze mail gerust negeren als je dit niet zelf gedaan hebt." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Aanmeldcode" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Je wachtwoord is gewijzigd." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Wachtwoord gewijzigd" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Je ontvangt deze mail omdat er een verzoek is ingelegd om je wachtwoord " "opnieuw\n" "in te stellen. Je kunt deze mail gerust negeren als je dit niet zelf gedaan\n" "hebt. Anders, klik op de volgende link om je wachtwoord opnieuw in te " "stellen." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Deze link hoort bij je account met gebruikersnaam %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Nieuw wachtwoord" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Je wachtwoord is opnieuw ingesteld." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Nieuw wachtwoord" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Je wachtwoord is ingesteld." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Wachtwoord ingesteld" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Je ontvang deze e-mail omdat jij, of iemand anders, een poging gedaan heeft " "een account met e-mailadres %(email)s te gebruiken. Echter, dit account " "bestaat niet." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Als jij dit wel hebt gedaan, dan kun je je via de volgende link registreren." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Onbekend account" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "E-mailadres" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Huidig email" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Wordt veranderd in" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Je e-mailadres wacht op verificatie." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Annuleer wijziging" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Wijzig naar" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "E-mail wijzigen" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Bevestig e-mailadres" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Bevestig dat %(email)s een e-mailadres is " "voor gebruiker %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Het e-mail adres %(email)s kon niet worden geverifieerd omdat het gekoppeld " "is aan een ander account." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Deze e-mail verificatie link is verlopen of niet geldig. Dien een\n" "nieuw e-mail verificatie verzoek in." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Als je nog geen account hebt %(link)sregistreer%(end_link)s je dan eerst." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Meld je aan met een passkey" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Mail een aanmeldcode" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Afmelden" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Weet je zeker dat je wilt afmelden?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "You kunt je primaire e-mailadres (%(email)s) niet verwijderen." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Bevestigings e-mail verzonden aan %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Je hebt het e-mailadres %(email)s bevestigd" #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "E-mailadres %(email)s verwijderd." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Je bent nu ingelogd als %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Je bent afgemeld." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Een aanmeldcode is verstuurd naar %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Wachtwoord wijziging geslaagd." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Je wachtwoord is gewijzigd." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primair e-mailadres ingesteld." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Wachtwoord wijzigen" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Wachtwoord vergeten?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Wachtwoord vergeten? Vul je e-mailadres in en we sturen je een e-mail " "waarmee je een nieuw wachtwoord kunt instellen." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Herstel mijn wachtwoord" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Neem a.u.b. contact met ons op als het niet lukt je wachtwoord opnieuw in te " "stellen." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Volg de link in de verificatie e-mail om de controle af te ronden. Neem a.u." "b. contact met ons op als je de e-mail niet binnen enkele minuten ontvangt." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Ongeldige sleutel" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "De link om je wachtwoord opnieuw in te stellen is niet geldig. Mogelijk is " "deze al een keer gebruikt. Herstel je " "wachtwoord opnieuw." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Je wachtwoord is gewijzigd." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Zet wachtwoord" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Voer je wachtwoord in:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Je zult een e-mail ontvangen met daarin een speciale aanmeldcode zodat je " "geen wachtwoord hoeft in te vullen." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Code aanvragen" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Andere aanmeld-opties" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registreren" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registreren" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Heb je al een account? %(link)sMeld je dan aan%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Registreren met een passkey" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Passkey registratie" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Andere opties" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registratie gesloten" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Helaas, maar je kunt je momenteel niet registreren." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Notitie" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Je bent al ingelogd als %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Waarschuwing:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Het is raadzaam een e-mailadres toe te voegen zodat je notificaties kunt " "ontvangen, je wachtwoord opnieuw kunt instellen, enz." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifieer je e-mailadres" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "We hebben een e-mail verstuurd ter verificatie. Volg de link in deze mail om " "je registratie af te ronden. Neem a.u.b. contact met ons op als je deze e-" "mail niet binnen enkele minuten ontvangt." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Voor dit gedeelte van de site is het nodig dat we je identiteit\n" "verifiëren. Via een verificatie e-mail kunnen we controleren dat je\n" "daadwerkelijk toegang hebt tot het opgegeven e-mailadres." #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Volg de link in de verificatie e-mail om de controle af te ronden. Neem a.u." "b. contact met ons op als je de e-mail niet binnen enkele minuten ontvangt." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Merk op: je kunt altijd je e-mail " "adres wijzigen." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Berichten:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Account Connecties" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Twee-factor-authenticatie" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sessies" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Je account is beveiligd met twee-factor-authenticatie. Voer alstublieft een " "authenticatiecode in:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Er zijn nieuwe herstelcodes gegenereerd." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Nieuwe herstelcodes gegenereerd" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Authenticator-app geactiveerd." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Authenticator-app geactiveerd" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Authenticator-app gedeactiveerd." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Authenticator-app gedeactiveerd" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Een nieuwe beveiligingssleutel is toegevoegd." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Beveiligingssleutel toegevoegd" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Een beveiligingssleutel is verwijderd." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Beveiligingssleutel verwijderd" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Authenticator-app" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Authenticatie middels een authenticator-app is actief." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Een authenticator-app is niet geactiveerd." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Deactiveer" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Activeer" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Beveiligingssleutels" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Je hebt %(count)s beveiligingssleutel toegevoegd." msgstr[1] "Je hebt %(count)s beveiligingssleutels toegevoegd." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Er zijn geen beveiligingssleutels gekoppeld." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Beheren" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Voeg toe" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Herstelcodes" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Er is nog %(unused_count)s van de %(total_count)s herstelcodes beschikbaar." msgstr[1] "" "Er zijn nog %(unused_count)s van de %(total_count)s herstelcodes beschikbaar." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Er zijn geen herstelcodes ingesteld." #: templates/mfa/index.html:96 msgid "View" msgstr "Bekijk" #: templates/mfa/index.html:102 msgid "Download" msgstr "Downloaden" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Genereer" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Er zijn nieuwe herstelcodes gegenereerd." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Beveiligingssleutel toegevoegd." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Beveiligingssleutel verwijderd." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Voer een authenticator code in:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Je staat op het punt nieuwe herstelcodes te genereren voor je account." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Hierdoor zullen eerdere herstelcodes niet langer werken." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Weet je dit zeker?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Ongebruikte codes" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Codes downloaden" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Nieuwe codes genereren" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Activeer authenticator-app" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Beveilig je account met twee-factor-authenticatie. Scan eerst de " "onderstaande QR code met je authenticator app, en vul vervolgens de " "resulterende verificatie code in." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Authenticator geheim" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Je kunt deze code bewaren en later gebruiken om je authenticator app opnieuw " "te installeren." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Deactiveer authenticator-app" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Je staat op het punt authenticatie middels een authenticator-app te " "deactiveren. Wil je dit echt?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Voeg beveiligingssleutel toe" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Verwijder beveiligingssleutel" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Weet je zeker dat je deze beveiligingssleutel wilt verwijderen?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Gebruik" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Passkey" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Beveiligingssleutel" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Het is onduidelijk of deze sleutel een passkey betreft." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Ongespecificeerd" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Toegevoegd op %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Laatst gebruikt %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Bewerken" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Bewerk beveiligingssleutel" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Opslaan" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "Passkey aanmaken" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "Je staat op het punt een passkey aan te maken. Aangezen je later extra sleutels kunt toevoegen kun je deze een herkenbare naam geven om de sleutels uit elkaar te kunnen houden." #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "Maak aan" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Deze functionaliteit vereist JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Aanmelden Mislukt" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Er is een fout opgetreden toen we je wilde inloggen via je externe account." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Je kunt jezelf aanmelden met een van de volgende externe accounts:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Je hebt momenteel geen externe accounts gekoppeld." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Voeg een extern account toe" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "Een extern account van %(provider)s is gekoppeld aan je account." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Extern account gekoppeld" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "Een extern account van %(provider)s is ontkoppeld van je account." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Extern account ontkoppeld" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Koppel %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Je staat op het punt om een nieuw account van %(provider)s aan je account te " "koppelen." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Aanmelden via %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "Je staat op het punt om jezelf aan te melden via %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Ga verder" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Aanmelden geannuleerd" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Je hebt het aanmelden via een extern account geannuleerd. Als dit een " "vergissing was, meld je dan opnieuw aan." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Het externe account is gekoppeld." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Het externe account is ontkoppeld." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Om bij %(site_name)s in te kunnen loggen via %(provider_name)s hebben we de " "volgende gegevens nodig:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Of gebruik een derde partij" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Afgemeld van alle andere sessies." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Gestart op" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP adres" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Browser" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Laatst gezien op" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Huidig" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Elders uitloggen" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Gebruikerssessies" #: usersessions/models.py:92 msgid "session key" msgstr "sessie sleutel" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Account Connecties" #~ msgid "Use security key or device" #~ msgstr "Gebruik een beveiligingssleutel" #~ msgid "Add Security Key or Device" #~ msgstr "Beveiligingssleutel toevoegen" #~ msgid "Add key or device" #~ msgstr "Beveiligingssleutel toevoegen" #~ msgid "Security Keys and Devices" #~ msgstr "Beveiligingssleutels" #~ msgid "You have not added any security keys/devices." #~ msgstr "Je hebt geen beveiligingssleutels toegevoegd." #~ msgid "Edit Security Key or Device" #~ msgstr "Bewerk beveiligingssleutel" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Het wachtwoord moet minimaal {0} tekens bevatten." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Je ontvang deze e-mail omdat er een verzoek is ingelegd om het wachtwoord " #~ "te\n" #~ "veranderen van account met e-mailadres %(email)s. Echter, dit account " #~ "bestaat\n" #~ "niet.\n" #~ "\n" #~ "Je kunt deze e-mail negeren als jij dit verzoek niet zelf hebt ingelegd.\n" #~ "\n" #~ "Als jij dit wel hebt gedaan, dan kun je je via de volgende link " #~ "registreren." #~ msgid "The following email address is associated with your account:" #~ msgstr "De volgende e-mailadressen zijn gekoppeld aan jouw account:" #~ msgid "Change Email Address" #~ msgstr "Wijzig e-mailadres" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "" #~ "Om de beveiliging van je account te waarborgen, voert eerst je wachtwoord " #~ "in:" #, fuzzy #~| msgid "Generate" #~ msgid "Regenerate" #~ msgstr "Genereer" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Meld je aan met een van je bestaande externe accounts. Of, registreer voor een %(site_name)s account en " #~ "meld je hiermee aan:" #~ msgid "or" #~ msgstr "of" #~ msgid "change password" #~ msgstr "Wachtwoord wijzigen" #~ msgid "OpenID Sign In" #~ msgstr "Aanmelden via OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Dit e-mailadres is al geassocieerd met een ander account." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "We hebben je een e-mail verstuurd. Neem a.u.b. contact met ons op als je " #~ "deze niet binnen enkele minuten ontvangen hebt." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Je login en wachtwoord komen niet overeen." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Gebruikersnamen mogen alleen letters, cijfers en @/./+/-/_ bevatten." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Deze gebruikersnaam is al in gebruik. Kies a.u.b. een andere naam." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Aanmelden" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Je hebt bevestigd dat %(email)s een e-" #~ "mail adres is voor gebruiker %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "Bedankt voor het gebruik van onze site!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Bevestigings e-mail verzonden aan %(email)s" #~ msgid "Delete Password" #~ msgstr "Verwijder wachtwoord" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "" #~ "Je kunt je wachtwoord verwijderen omdat je via OpenID bent ingelogd." #~ msgid "delete my password" #~ msgstr "Verwijder mijn wachtwoord" #~ msgid "Password Deleted" #~ msgstr "Wachtwoord verwijderd" django-allauth-65.0.2/allauth/locale/pl/000077500000000000000000000000001467545753200200245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/pl/LC_MESSAGES/000077500000000000000000000000001467545753200216115ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/pl/LC_MESSAGES/django.po000066400000000000000000001576521467545753200234330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:09+0200\n" "Last-Translator: Krzysztof Hoffmann \n" "Language-Team: \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.3\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && " "(n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && " "n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Konto jest obecnie nieaktywne." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Nie możesz usunąć podstawowego adresu e-mail (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Ten adres e-mail jest już powiązany z tym kontem." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Podany adres e-mail i/lub hasło są niepoprawne." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "W systemie jest już zarejestrowany użytkownik o tym adresie e-mail." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Proszę wpisz swoje obecne hasło." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Błędny kod." #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Obecne hasło" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Nieprawidłowy klucz" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Token resetowania hasła był nieprawidłowy." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Nie możesz dodać więcej niż %d adresów e-mail." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Zbyt wiele nieudanych prób logowania. Spróbuj ponownie później." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Adres e-mail nie jest powiązany z żadnym kontem użytkownika" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Twój podstawowy adres e-mail musi być zweryfikowany." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Nie możesz użyć tej nazwy użytkownika. Proszę wybierz inną." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Podana nazwa użytkownika i/lub hasło są niepoprawne." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Nie pamiętasz hasła?" #: account/adapter.py:750 #, fuzzy #| msgid "Authenticator App" msgid "Use authenticator app or code" msgstr "Aplikacja autoryzacyjna" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "klucz prywatny" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Twój podstawowy adres e-mail musi być zweryfikowany." #: account/apps.py:11 msgid "Accounts" msgstr "Konta" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Musisz wpisać za każdym razem to samo hasło." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Hasło" #: account/forms.py:93 msgid "Remember Me" msgstr "Pamiętaj mnie" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Adres e-mail" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nazwa użytkownika" #: account/forms.py:123 msgid "Username or email" msgstr "Nazwa użytkownika lub e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Login" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Nie pamiętasz hasła?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (ponownie)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Powierdzenie adresu email" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (opcjonalnie)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Musisz wpisać za każdym razem ten sam e-mail." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Hasło (ponownie)" #: account/forms.py:554 msgid "Current Password" msgstr "Obecne hasło" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nowe hasło" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nowe hasło (ponownie)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kod" #: account/models.py:26 msgid "user" msgstr "użytkownik" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "adres e-mail" #: account/models.py:34 msgid "verified" msgstr "zweryfikowany" #: account/models.py:35 msgid "primary" msgstr "podstawowy" #: account/models.py:41 msgid "email addresses" msgstr "adresy e-mail" #: account/models.py:150 msgid "created" msgstr "utworzono" #: account/models.py:151 msgid "sent" msgstr "wysłano" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "klucz" #: account/models.py:157 msgid "email confirmation" msgstr "potwierdzenie adresu e-mail" #: account/models.py:158 msgid "email confirmations" msgstr "potwierdzenia adresów e-mail" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Nie można dodać adresu e-mail do konta chronionego dwuskładnikową " "autoryzacją." #: mfa/adapter.py:35 #, fuzzy #| msgid "" #| "You cannot add an email address to an account protected by two-factor " #| "authentication." msgid "You cannot deactivate two-factor authentication." msgstr "" "Nie można dodać adresu e-mail do konta chronionego dwuskładnikową " "autoryzacją." #: mfa/adapter.py:38 #, fuzzy #| msgid "" #| "You cannot add an email address to an account protected by two-factor " #| "authentication." msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Nie można dodać adresu e-mail do konta chronionego dwuskładnikową " "autoryzacją." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Nie możesz aktywować uwierzytelniania dwuskładnikowego dopóki nie " "zweryfikujesz swojego adresu e-mail." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "klucz prywatny" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Kody odzyskiwania" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Autentykator TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Kod autentykacyjny" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Hasło" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Istnieje już konto dla tego adresu e-mail. Zaloguj się najpierw na to konto, " "a następnie połącz swoje konto %s." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Nieprawidłowy klucz" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Twoje konto nie posiada hasła." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Twoje konto nie ma zweryfikowanego adresu e-mail." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Możesz zalogować się do swojego konta używając dowolnego z poniższych kont " "zewnętrznych:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "To konto społecznościowe jest już połączone z innym kontem." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Konta społecznościowe" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "dostawca usług" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "dostawca usług" #: socialaccount/models.py:56 msgid "name" msgstr "nazwa" #: socialaccount/models.py:58 msgid "client id" msgstr "id klienta" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID aplikacji lub klucz odbiorcy" #: socialaccount/models.py:63 msgid "secret key" msgstr "klucz prywatny" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Klucz prywatny API, klienta lub odbiorcy" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Klucz" #: socialaccount/models.py:81 msgid "social application" msgstr "aplikacja społecznościowa" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplikacje społecznościowe" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "data ostatniego logowania" #: socialaccount/models.py:120 msgid "date joined" msgstr "data przyłączenia" #: socialaccount/models.py:121 msgid "extra data" msgstr "dodatkowe dane" #: socialaccount/models.py:125 msgid "social account" msgstr "konto społecznościowe" #: socialaccount/models.py:126 msgid "social accounts" msgstr "konta społecznościowe" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) lub access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token secret" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) lub refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "wygasa" #: socialaccount/models.py:174 msgid "social application token" msgstr "token aplikacji społecznościowej" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokeny aplikacji społecznościowych" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Nieprawidłowe dane profilu" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Login" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Anuluj" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Błędna odpowiedź podczas pobierania tokena z \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Błędna odpowiedź podczas pobierania tokena autoryzacji z \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Brak tokena zapisanego dla \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Brak zapisanego tokena autoryzacji \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Brak dostępu do prywatnych zasobów na \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Błędna odpowiedź podczas pobierania tokena z \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Konto nieaktywne" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "To konto jest nieaktywne." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Potwierdź adres e-mail" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "potwierdzenie adresu e-mail" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Authenticator code" msgid "Enter Email Verification Code" msgstr "Kod autentykacyjny" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Potwierdź" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Zaloguj" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Adresy e-mail" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Poniższe adresy e-mail są powiązane z Twoim kontem:" #: templates/account/email.html:25 msgid "Verified" msgstr "Zweryfikowany" #: templates/account/email.html:29 msgid "Unverified" msgstr "Brak weryfikacji" #: templates/account/email.html:34 msgid "Primary" msgstr "Podstawowy" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Uczyń podstawowym" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Prześlij ponownie wiadomość weryfikacyjną" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Usuń" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Dodaj adres e-mail" #: templates/account/email.html:70 msgid "Add Email" msgstr "Dodaj e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Czy naprawdę chcesz usunąć wybrany adres e-mail?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Otrzymujesz tę wiadomość e-mail, ponieważ Ty lub ktoś inny próbował " "zarejestrować konto używając adresu e-mail:\n" "\n" "%(email)s\n" "\n" "Jednakże, konto z tym adresem e-mail już istnieje. Jeśli o tym zapomniałeś, " "proszę skorzystaj z procedury odzyskiwania hasła, aby odzyskać dostęp do " "swojego konta:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Konto już istnieje." #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Witamy z %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Dziękujemy za korzystanie z %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Cancel" msgid "Email Changed" msgstr "Anuluj" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your email has been confirmed." msgstr "Twoje hasło zostało skasowane." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "potwierdzenie adresu e-mail" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Otrzymujesz ten e-mail, ponieważ użytkownik %(user_display)s podał niniejszy " "adres e-mail, aby powiązać go z swoim kontem w serwisie %(site_domain)s.\n" "\n" "Aby potwierdzić powiązanie, kliknij w link %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Proszę potwierdź adres e-mail" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Usuń" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Zaloguj" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Twoje hasło zostało zmienione." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Hasło (ponownie)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Otrzymujesz tę wiadomość, ponieważ Ty lub ktoś inny poprosił o zresetowanie " "hasła do Twojego konta.\n" "Niniejszą wiadomość możesz spokojnie zignorować, jeżeli prośba nie " "pochodziła od Ciebie. Kliknij w link poniżej, aby zresetować hasło." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "" "Na wszelki wypadek przypominamy, że Twoja nazwa użytkownika to %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail z łączem do zmiany hasła" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been reset." msgstr "Twoje hasło zostało skasowane." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Resetowanie hasła" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been set." msgstr "Twoje hasło zostało skasowane." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Resetowanie hasła" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Konto" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Adresy e-mail" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Obecne hasło" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Twój podstawowy adres e-mail musi być zweryfikowany." #: templates/account/email_change.html:41 #, fuzzy #| msgid "Cancel" msgid "Cancel Change" msgstr "Anuluj" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Potwierdź adres e-mail" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Proszę potwierdź, że adres %(email)s jest " "adresem e-mail dla użytkownika %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "To konto społecznościowe jest już połączone z innym kontem." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Łącze z adresem do zresetowania hasła wygasło lub jest niepoprawne. wygenerować nowe łącze dla Twojego adresu. ." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Jeżeli nie masz jeszcze konta, to proszę %(link)szarejestruj się%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Wyloguj się" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Czy na pewno chcesz się wylogować ?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Nie możesz usunąć podstawowego adresu e-mail (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "E-mail z potwierdzeniem został wysłany na adres %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Adres %(email)s został potwierdzony." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Adres e-mail %(email)s został usunięty." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Zalogowano jako %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Wylogowano." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Hasło zostało zmienione." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Hasło zostało ustawione." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Podstawowy adres e-mail został ustawiony." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Zmień hasło" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Nie pamiętasz hasła?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Nie pamiętasz swojego hasła? Wpisz swój adres e-mail poniżej, a my wyślemy " "Ci wiadomość, dzięki której dokonasz jego zmiany." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Zresetuj moje hasło" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Skontaktuj się z nami, jeśli masz problem ze zresetowaniem swojego hasła." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Wysłaliśmy Ci wiadomość e-mail.\n" "W celu weryfikacji musisz kliknąć w łącze zawarte w wiadomości. Proszę " "skontaktuj się z nami, jeśli nie dotarła do Ciebie w ciągu kilku minut." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Nieprawidłowy klucz" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Łącze resetujące hasło jest niepoprawne, prawdopodobnie zostało już użyte. " "Zresetuj hasło jeszcze raz." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Twoje hasło zostało zmienione." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Ustaw hasło" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Nie pamiętasz hasła?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 #, fuzzy #| msgid "Recovery Codes" msgid "Request Code" msgstr "Kody odzyskiwania" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Zarejestruj się" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Zarejestruj się" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Masz już konto? Jeżeli tak, to %(link)szaloguj się%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Zarejestruj się" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Rejestracja zamknięta" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Przepraszamy, ale w tej chwili rejestracja jest zamknięta." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Uwaga" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "jesteś już zalogowany/-a jako %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Uwaga:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Aktualnie nie posiadasz przypisanych do twojego konta adresów e-mail. Warto " "dodać taki adres, aby otrzymywać informacje administracyjne, wiadomości o " "zmianie hasła, itd." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Zweryfikuj swój adres e-mail" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Przesłaliśmy weryfikacyjny e-mail na twój adres. Kliknij w łącze w " "wiadomości, aby zakończyć proces rejestracji. Skontaktuj się z nami, jeśli " "nie otrzymasz jej w ciągu kilku minut." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Ta część strony wymaga weryfikacji tego, kim jesteś. Dlatego wymagamy " "weryfikacji Twojego adresu e-mail." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Wysłaliśmy Ci wiadomość e-mail.\n" "W celu weryfikacji musisz kliknąć w łącze zawarte w wiadomości. Proszę " "skontaktuj się z nami, jeśli nie dotarła do Ciebie w ciągu kilku minut." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Uwaga: możesz ciągle zmienić Twój " "adres e-mail." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Wiadomości:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Połączone konta" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Autoryzacja dwuskładnikowa" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Twoje konto jest chronione przez uwierzytelnianie dwuskładnikowe. Proszę " "wprowadzić kod uwierzytelniający:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Wygenerowano nowy zestaw kodów odzyskiwania." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 #, fuzzy #| msgid "Recovery Codes" msgid "New Recovery Codes Generated" msgstr "Kody odzyskiwania" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Aplikacja autoryzacyjna została aktywowana." #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "Authenticator app activated." msgid "Authenticator App Activated" msgstr "Aplikacja autoryzacyjna została aktywowana." #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Aplikacja autoryzacyjna została dezaktywowana." #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "Authenticator app deactivated." msgid "Authenticator App Deactivated" msgstr "Aplikacja autoryzacyjna została dezaktywowana." #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "Wygenerowano nowy zestaw kodów odzyskiwania." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "A security key has been removed." msgstr "Twoje hasło zostało skasowane." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Aplikacja autoryzacyjna" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Autoryzacja za pomocą aplikacji autoryzacyjnej jest aktywna." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Aplikacja autoryzacyjna nie jest aktywna." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Dezaktywuj" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Aktywuj" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Kody odzyskiwania" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Dostępnych jest %(unused_count)s z %(total_count)s kodów odzyskiwania." msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Nie ustawiono żadnych kodów odzyskiwania." #: templates/mfa/index.html:96 msgid "View" msgstr "Widok" #: templates/mfa/index.html:102 msgid "Download" msgstr "Pobierz" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Generuj" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Wygenerowano nowy zestaw kodów odzyskiwania." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "Authenticator code" msgid "Enter an authenticator code:" msgstr "Kod autentykacyjny" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Zaraz wygenerujesz nowy zestaw kodów odzyskiwania dla Twojego konta." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Ta czynność spowoduje unieważnienie istniejących kodów." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Jesteś pewny?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Niewykorzystane kody" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Pobierz kody" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Wygeneruj nowe kody." #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Aktywuj aplikację uwierzytelniającą." #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Aby zabezpieczyć swoje konto za pomocą uwierzytelniania dwuskładnikowego, " "zeskanuj poniższy kod QR za pomocą aplikacji uwierzytelniającej. Następnie " "wprowadź poniżej kod weryfikacyjny wygenerowany przez aplikację." #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "token secret" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Możesz przechować ten sekret i użyć go później do ponownej instalacji " "aplikacji uwierzytelniającej." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Wyłącz aplikację uwierzytelniającą." #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Zamierzasz wyłączyć uwierzytelnianie oparte na aplikacji Authenticator. " "Jesteś pewien?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "klucz prywatny" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "klucz prywatny" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Czy na pewno chcesz się wylogować ?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "klucz prywatny" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Brak weryfikacji" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "klucz prywatny" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Obecne hasło" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "utworzono" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Błędne logowanie z konta społecznościowego" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Wystąpił błąd podczas próby logowania za pomocą konta społecznościowego." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Możesz zalogować się do swojego konta używając dowolnego z poniższych kont " "zewnętrznych:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Nie masz obecnie żadnych kont społecznościowych połączonych z tym kontem." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Dodaj konto zewnętrzne" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Dodaj konto zewnętrzne" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Dodaj konto zewnętrzne" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Połącz z %(provider)s." #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Zamierzasz połączyć nowe konto zewnętrzne od dostawcy %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Zaloguj się za pomocą %(provider)s." #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Zamierzasz zalogować się przy użyciu konta zewnętrznego dostawcy " "%(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Kontynuuj" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Logowanie anulowane" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Wybrano anulowanie logowania przez jedno z istniejących kont. Jeżeli to była " "pomyłka, proszę przejdź do zaloguj." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Konto społecznościowe zostało połączone." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Konto społecznościowe zostało rozłączone." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Masz zamiar użyć konta %(provider_name)s do zalogowania się w \n" "%(site_name)s. Jako ostatni krok, proszę wypełnij formularz:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Lub skorzystaj z serwisów społecznościowych" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Adresy e-mail" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Obecne hasło" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Połączone konta" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Hasło musi składać się z co najmniej {0} znaków." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Otrzymujesz tę wiadomość, ponieważ Ty lub ktoś inny poprosił o " #~ "zresetowanie hasła do Twojego konta.\n" #~ "Niniejszą wiadomość możesz spokojnie zignorować, jeżeli prośba nie " #~ "pochodziła od Ciebie. Kliknij w link poniżej, aby zresetować hasło." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Poniższe adresy e-mail są powiązane z Twoim kontem:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Potwierdź adres e-mail" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "Dla bezpieczeństwa konta, prosimy o podanie hasła:" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Proszę zaloguj się jednym\n" #~ "z Twoich zewnętrznych kont. Lub %(link)szarejestruj się \n" #~ "w %(site_name)s i zaloguj poniżej:" #~ msgid "or" #~ msgstr "lub" #~ msgid "change password" #~ msgstr "zmień hasło" #~ msgid "OpenID Sign In" #~ msgstr "Zaloguj przez OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Ten adres e-mail jest już powiązany z innym kontem." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Wysłaliśmy Ci e-mail. Proszę skontaktuj się z nami, jeśli go nie " #~ "otrzymasz w ciągu paru minut." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Login i/lub hasło, które podałeś, są niepoprawne." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Nazwa użytkownika może zawierać tylko litery, cyfry oraz znaki @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Nazwa użytkownika jest już w użyciu. Proszę wybierz inną." #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Potwierdziłeś, że adres %(email)s jest " #~ "adresem e-mail użytkownika %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "Dziękujemy za używanie naszej strony!" #~ msgid "Socialaccount" #~ msgstr "Konta społecznościowe" #~ msgid "Key (Stack Exchange only)" #~ msgstr "Klucz (tylko dla Stack Exchange)" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Wiadomość z potwierdzeniem została wysłana na adres %(email)s" #~ msgid "Delete Password" #~ msgstr "Skasuj hasło" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "Możesz skasować swoje hasło jeśli używasz OpenID." #~ msgid "delete my password" #~ msgstr "skasuj moje hasło" #~ msgid "Password Deleted" #~ msgstr "Hasło Skasowane" django-allauth-65.0.2/allauth/locale/pt_BR/000077500000000000000000000000001467545753200204175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/pt_BR/LC_MESSAGES/000077500000000000000000000000001467545753200222045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/pt_BR/LC_MESSAGES/django.po000066400000000000000000001435071467545753200240200ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Renato De Giovanni , 2022 # cacarrara , 2014 # Fábio C. Barrionuevo da Luz , 2013-2014 # Rodrigo , 2013 # Rodrigo , 2013-2014 msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-08-30 07:32+0000\n" "Last-Translator: Alefsander Ribeiro Nascimento \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.7.1-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Esta conta está atualmente inativa." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Você não pode remover seu endereço de e-mail principal." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Este endereço de e-mail já está associado a esta conta." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "O endereço de e-mail e/ou senha especificados estão incorretos." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Um usuário já está registrado com este endereço de e-mail." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Por favor, digite sua senha atual." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Código incorreto." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Senha incorreta." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Chave inválida ou expirada." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "O token de redefinição de senha era inválido." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Você não pode adicionar mais de %d endereços de e-mail." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Muitas tentativas de login falharam. Tente novamente mais tarde." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "O endereço de e-mail não está atribuído a nenhuma conta de usuário" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Seu endereço de e-mail principal deve ser verificado." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Nome de usuário não pode ser utilizado. Por favor, use outro nome de usuário." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "O nome de usuário e/ou senha especificados estão incorretos." #: account/adapter.py:741 msgid "Use your password" msgstr "Use sua senha" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Use um aplicativo autenticador ou código" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Use uma chave de segurança" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Marcar os endereços de e-mail selecionados como verificados" #: account/apps.py:11 msgid "Accounts" msgstr "Contas" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Você deve digitar a mesma senha todas as vezes." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Senha" #: account/forms.py:93 msgid "Remember Me" msgstr "Lembrar de Mim" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Endereço de e-mail" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nome de usuário" #: account/forms.py:123 msgid "Username or email" msgstr "Nome de usuário ou e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Login" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Esqueceu sua senha?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (novamente)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Confirmação de endereço de e-mail" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (opcional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Você deve digitar o mesmo e-mail todas as vezes." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Senha (novamente)" #: account/forms.py:554 msgid "Current Password" msgstr "Senha atual" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nova senha" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nova senha (novamente)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Código" #: account/models.py:26 msgid "user" msgstr "usuário" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "endereço de e-mail" #: account/models.py:34 msgid "verified" msgstr "verificado" #: account/models.py:35 msgid "primary" msgstr "principal" #: account/models.py:41 msgid "email addresses" msgstr "endereços de e-mail" #: account/models.py:150 msgid "created" msgstr "criado" #: account/models.py:151 msgid "sent" msgstr "enviado" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "chave" #: account/models.py:157 msgid "email confirmation" msgstr "confirmação de e-mail" #: account/models.py:158 msgid "email confirmations" msgstr "confirmações de e-mail" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "Você não pode adicionar um endereço de e-mail a uma conta protegida por autenticação de dois fatores." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Você não pode desativar a autenticação de dois fatores." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "Você não pode gerar códigos de recuperação sem ter a autenticação de dois fatores ativada." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "Você não pode ativar a autenticação de dois fatores até que tenha verificado seu endereço de e-mail." #: mfa/adapter.py:141 msgid "Master key" msgstr "Chave mestre" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Chave de backup" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Chave nº {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Códigos de recuperação" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Autenticador TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Código do autenticador" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Sem senha" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "Ativar a operação sem senha permite que você faça login apenas com esta chave, mas impõe requisitos adicionais, como biometria ou proteção com PIN." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "Uma conta já existe com este endereço de e-mail. Faça login nessa conta primeiro e depois conecte sua conta %s." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Token inválido." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Sua conta não tem senha configurada." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Sua conta não tem um endereço de e-mail verificado." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Você não pode desconectar sua última conta de terceiros conectada." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "A conta de terceiros já está conectada a uma conta diferente." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Contas sociais" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "provedor" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID do provedor" #: socialaccount/models.py:56 msgid "name" msgstr "nome" #: socialaccount/models.py:58 msgid "client id" msgstr "ID do cliente" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID do aplicativo ou chave do consumidor" #: socialaccount/models.py:63 msgid "secret key" msgstr "chave secreta" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Segredo da API, segredo do cliente ou segredo do consumidor" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Chave" #: socialaccount/models.py:81 msgid "social application" msgstr "aplicativo social" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplicativos sociais" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "último login" #: socialaccount/models.py:120 msgid "date joined" msgstr "data de entrada" #: socialaccount/models.py:121 msgid "extra data" msgstr "dados adicionais" #: socialaccount/models.py:125 msgid "social account" msgstr "conta social" #: socialaccount/models.py:126 msgid "social accounts" msgstr "contas sociais" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ou token de acesso (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "segredo do token" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ou token de atualização (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "expira em" #: socialaccount/models.py:174 msgid "social application token" msgstr "token de aplicativo social" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokens de aplicativos sociais" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Dados de perfil inválidos" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Login" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Cancelar" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Resposta inválida ao obter o token de solicitação de \"%s\". A resposta foi: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Resposta inválida ao obter o token de acesso de \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Nenhum token de solicitação salvo para \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Nenhum token de acesso salvo para \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Sem acesso a recursos privados em \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Resposta inválida ao obter o token de solicitação de \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Conta inativa" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Esta conta está inativa." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Confirmar acesso" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Por favor, reautentique para proteger sua conta." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Opções alternativas" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "Verificação de e-mail" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Insira o código de verificação de e-mail" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "Enviamos um código para %(email_link)s. O código expira em breve, então insira-o logo." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Confirmar" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Entrar" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Insira o código de entrada" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Endereços de e-mail" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Os seguintes endereços de e-mail estão associados à sua conta:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verificado" #: templates/account/email.html:29 msgid "Unverified" msgstr "Não verificado" #: templates/account/email.html:34 msgid "Primary" msgstr "Principal" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Tornar principal" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Reenviar verificação" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Remover" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Adicionar endereço de e-mail" #: templates/account/email.html:70 msgid "Add Email" msgstr "Adicionar e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Você realmente deseja remover o endereço de e-mail selecionado?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Você está recebendo este e-mail porque você ou outra pessoa tentou se " "inscrever para\n" "uma conta usando o endereço de e-mail:\n" "\n" "%(email)s\n" "\n" "No entanto, uma conta com este endereço de e-mail já existe. Caso você tenha\n" "esquecido disso, por favor use o procedimento de recuperação de senha para\n" "recuperar sua conta:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Conta já existente" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Olá da %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Obrigado por usar %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Você está recebendo este e-mail porque a seguinte alteração foi feita em sua conta:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Se você não reconhece essa alteração, por favor tome as devidas precauções de segurança imediatamente. A alteração em sua conta se origina de:\n" "\n" "- Endereço IP: %(ip)s\n" "- Navegador: %(user_agent)s\n" "- Data: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Seu e-mail foi alterado de %(from_email)s para %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E-mail alterado" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Seu e-mail foi confirmado." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Confirmação de e-mail" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Você está recebendo este e-mail porque o usuário %(user_display)s forneceu seu\n" "endereço de e-mail para registrar uma conta em %(site_domain)s." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "Seu código de verificação de e-mail está listado abaixo. Por favor, insira-o na janela do seu navegador aberta." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Para confirmar que isso está correto, acesse %(activate_url)s." #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Por favor, confirme seu endereço de e-mail." #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "O endereço de e-mail %(deleted_email)s foi removido de sua conta." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "E-mail removido" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "Seu código de entrada está listado abaixo. Por favor, insira-o na janela do seu navegador aberta." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Este e-mail pode ser ignorado com segurança se você não iniciou esta ação." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Código de entrada" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Sua senha foi alterada." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Senha alterada" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Você está recebendo este e-mail porque você ou outra pessoa solicitou a redefinição de senha para sua conta de usuário.\n" "Este e-mail pode ser ignorado com segurança se você não solicitou a redefinição de senha. Clique no link abaixo para redefinir sua senha." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Caso tenha esquecido, seu nome de usuário é %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail de redefinição de senha" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Sua senha foi redefinida." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Redefinição de senha" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Sua senha foi definida." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Senha definida" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Você está recebendo este e-mail porque você, ou outra pessoa, tentou acessar uma conta com o e-mail %(email)s. No entanto, não temos nenhum registro de tal conta em nosso banco de dados." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "Se foi você, pode se inscrever para uma conta usando o link abaixo." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Conta desconhecida" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Endereço de e-mail" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "E-mail atual" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Alterando para" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Seu endereço de e-mail ainda está aguardando verificação." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Cancelar alteração" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Alterar para" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Alterar e-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Confirmar endereço de e-mail" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Por favor, confirme que %(email)s é um endereço de e-mail para o usuário %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Incapaz de confirmar %(email)s porque já foi confirmado por uma conta diferente." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Este link de confirmação de e-mail expirou ou é inválido. Por favor, emita uma nova solicitação de confirmação de e-mail." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Se você ainda não criou uma conta, por favor, %(link)scadastre-se%(end_link)s primeiro." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Entrar com uma chave de segurança" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Envie-me um código de entrada por e-mail." #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Sair" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Tem certeza de que deseja sair?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Você não pode remover seu endereço de e-mail principal (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "E-mail de confirmação enviado para %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Você confirmou %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Endereço de e-mail removido %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Conectado com sucesso como %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Você saiu." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Um código de entrada foi enviado para %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Senha alterada com sucesso." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Senha definida com sucesso." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Endereço de e-mail principal definido." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Alterar senha" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Esqueceu a senha?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Esqueceu sua senha? Insira seu endereço de e-mail abaixo e nós enviaremos um e-mail permitindo que você a redefina." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Redefinir minha senha" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Por favor, entre em contato conosco se tiver algum problema ao redefinir sua senha." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Enviamos um e-mail para você. Se você não o recebeu, por favor, verifique sua pasta de spam. Caso contrário, entre em contato conosco se não o receber em alguns minutos." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Token inválido" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "O link de redefinição de senha era inválido, possivelmente porque já foi utilizado. Por favor, solicite uma nova redefinição de senha." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Sua senha foi alterada." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Definir senha" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Insira sua senha:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "Você receberá um e-mail contendo um código especial para uma entrada sem senha." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Solicitar código" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Outras opções de entrada" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Cadastrar-se" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Cadastrar-se" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Já tem uma conta? Então, por favor, %(link)ssign in%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Cadastrar-se usando uma chave de segurança" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Cadastro com chave de segurança" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Outras opções" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Cadastro fechado" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Desculpe, mas o cadastro está atualmente fechado." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Nota" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Você já está conectado como %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Aviso:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Atualmente, você não tem nenhum endereço de e-mail configurado. Você deve realmente adicionar um endereço de e-mail para que possa receber notificações, redefinir sua senha, etc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifique seu endereço de e-mail" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Enviamos um e-mail para você para verificação. Siga o link fornecido para finalizar o processo de cadastro. Se você não encontrar o e-mail de verificação em sua caixa de entrada principal, verifique sua pasta de spam. Entre em contato conosco se não receber o e-mail de verificação dentro de alguns minutos." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Esta parte do site exige que verifiquemos que você é quem afirma ser. Para esse fim, exigimos que você\n" "verifique a propriedade do seu endereço de e-mail. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Enviamos um e-mail para você para verificação. Por favor, clique no link dentro desse e-mail. Se você não encontrar o e-mail de verificação em sua caixa de entrada principal, verifique sua pasta de spam. Caso contrário, entre em contato conosco se não o receber dentro de alguns minutos." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Nota: você ainda pode alterar seu endereço de e-mail." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Mensagens:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Conexões de conta" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Autenticação de dois fatores" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Sessões" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Sua conta está protegida por autenticação de dois fatores. Por favor, insira um código do autenticador:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Um novo conjunto de códigos de recuperação da autenticação de dois fatores foi gerado." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Novos códigos de recuperação gerados" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Aplicativo autenticador ativado." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Aplicativo autenticador ativado" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Aplicativo autenticador desativado." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Aplicativo autenticador desativado" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Uma nova chave de segurança foi adicionada." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Chave de segurança adicionada" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Uma chave de segurança foi removida." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Chave de segurança removida" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Aplicativo autenticador" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "A autenticação usando um aplicativo autenticador está ativa." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Um aplicativo autenticador não está ativo." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Desativar" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Ativar" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Chaves de segurança" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Você adicionou %(count)s chave de segurança." msgstr[1] "Você adicionou %(count)s chaves de segurança." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Nenhuma chave de segurança foi adicionada." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Gerenciar" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Adicionar" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Códigos de recuperação" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "Há %(unused_count)s de %(total_count)s códigos de recuperação disponíveis." msgstr[1] "Há %(unused_count)s de %(total_count)s códigos de recuperação disponíveis." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Nenhum código de recuperação configurado." #: templates/mfa/index.html:96 msgid "View" msgstr "Visualizar" #: templates/mfa/index.html:102 msgid "Download" msgstr "Baixar" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Gerar" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Um novo conjunto de códigos de recuperação foi gerado." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Chave de segurança adicionada." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Chave de segurança removida." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Insira um código do autenticador:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Você está prestes a gerar um novo conjunto de códigos de recuperação para sua conta." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Esta ação invalidará seus códigos existentes." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Você tem certeza?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Códigos não utilizados" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Baixar códigos" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Gerar novos códigos" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Ativar aplicativo autenticador" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Para proteger sua conta com autenticação de dois fatores, escaneie o código QR abaixo com seu aplicativo autenticador. Em seguida, insira o código de verificação gerado pelo aplicativo abaixo." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Segredo do autenticador" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "Você pode armazenar este segredo e usá-lo para reinstalar seu aplicativo autenticador posteriormente." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Desativar aplicativo autenticador" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Você está prestes a desativar a autenticação baseada em aplicativo autenticador. Você tem certeza?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Adicionar chave de segurança" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Remover chave de segurança" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Tem certeza de que deseja remover esta chave de segurança?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Uso" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Chave de segurança" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Chave de segurança" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Esta chave não indica se é uma chave de segurança." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Não especificado" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Adicionado em %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Último uso em %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Editar" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Editar chave de segurança" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Salvar" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "Criar chave de segurança" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" "Você está prestes a criar uma chave de segurança para sua conta. Como você pode adicionar chaves adicionais posteriormente, pode usar um nome descritivo para diferenciar as chaves." #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "Criar" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Esta funcionalidade requer JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Falha no login de terceiros" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Ocorreu um erro ao tentar fazer login via sua conta de terceiros." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Você pode fazer login em sua conta usando qualquer uma das seguintes contas de terceiros:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Atualmente, você não tem contas de terceiros conectadas a esta conta." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Adicionar uma conta de terceiros" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "Uma conta de terceiros de %(provider)s foi conectada à sua conta." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Conta de terceiros conectada" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "Uma conta de terceiros de %(provider)s foi desconectada de sua conta." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Conta de terceiros desconectada" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Conectar %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Você está prestes a conectar uma nova conta de terceiros de %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Entrar via %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "Você está prestes a fazer login usando uma conta de terceiros de %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Continuar" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Login cancelado" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Você decidiu cancelar o login em nosso site usando uma de suas contas existentes. Se isso foi um erro, por favor, continue para fazer login." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "A conta de terceiros foi conectada." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "A conta de terceiros foi desconectada." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Você está prestes a usar sua conta %(provider_name)s para fazer login em\n" "%(site_name)s. Como passo final, por favor, complete o formulário a seguir:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Ou use uma conta de terceiros" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Saiu de todas as outras sessões." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Iniciado em" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "Endereço IP" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Navegador" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Última visualização em" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Atual" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Sair de outras sessões" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Sessões de usuário" #: usersessions/models.py:92 msgid "session key" msgstr "chave da sessão" django-allauth-65.0.2/allauth/locale/pt_PT/000077500000000000000000000000001467545753200204375ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/pt_PT/LC_MESSAGES/000077500000000000000000000000001467545753200222245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/pt_PT/LC_MESSAGES/django.po000066400000000000000000001467321467545753200240430ustar00rootroot00000000000000# Portuguese from Portugal translation for django-allauth. # Copyright (C) 2023 # This file is distributed under the same license as the django-allauth package. # # Translators: # Fábio Santos, 2012 # Emanuel Angelo , 2023. # msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:05+0200\n" "Last-Translator: Emanuel Angelo \n" "Language-Team: Portuguese (Portugal)\n" "Language: pt_PT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.3.2\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Esta conta está atualmente inativa." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Não pode remover o seu endereço de email primário (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Este endereço de email já está associado a esta conta." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "" "O endereço de email e/ou a palavra-passe que especificou não estão corretos." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Já existe um utilizador registado com este endereço de email." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Por favor insira a sua palavra-passe atual." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Código errado." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Palavra-passe errada." #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Código errado" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "O código para redefinir a palavra-passe era inválido." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Não pode adicionar mais do que %d endereços de email." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Demasiadas tentativas falhadas para iniciar sessão. Tente novamente mais " "tarde." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "O endereço de email não está associado a nenhuma conta" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "O seu endereço de email primário tem de ser verificado." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Esse nome de utilizador não pode ser utilizado. Por favor, use outro." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "" "O nome de utilizador e/ou a palavra-passe que especificou não estão corretos." #: account/adapter.py:741 msgid "Use your password" msgstr "Utilizar palavra-passe" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "Utilizar autenticador" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "chave secreta" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Marcar endereços de e-mail selecionados como verificados" #: account/apps.py:11 msgid "Accounts" msgstr "Contas" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Tem que escrever a mesma palavra-passe em ambos os campos." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Palavra-passe" #: account/forms.py:93 msgid "Remember Me" msgstr "Lembrar-me" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Endereço de email" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Email" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nome de utilizador" #: account/forms.py:123 msgid "Username or email" msgstr "Nome de utilizador ou email" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Iniciar sessão" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Esqueceu-se da sua palavra-passe?" #: account/forms.py:299 msgid "Email (again)" msgstr "Email (novamente)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Confirmação do endereço de email" #: account/forms.py:311 msgid "Email (optional)" msgstr "Email (opcional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "deve escrever o mesmo endereço de email em ambos os campos." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Palavra-passe (novamente)" #: account/forms.py:554 msgid "Current Password" msgstr "Palavra-passe atual" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nova palavra-passe" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nova palavra-passe (novamente)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Código" #: account/models.py:26 msgid "user" msgstr "utilizador" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "endereço de email" #: account/models.py:34 msgid "verified" msgstr "verificado" #: account/models.py:35 msgid "primary" msgstr "primário" #: account/models.py:41 msgid "email addresses" msgstr "endereços de email" #: account/models.py:150 msgid "created" msgstr "criado" #: account/models.py:151 msgid "sent" msgstr "enviado" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "chave" #: account/models.py:157 msgid "email confirmation" msgstr "confirmação de email" #: account/models.py:158 msgid "email confirmations" msgstr "confirmações de email" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Não pode adicionar um endereço de email a uma conta que esteja protegida por " "autenticação de dois factores." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Não pode desativar a autenticação de dois fatores." #: mfa/adapter.py:38 #, fuzzy #| msgid "You cannot deactivate two-factor authentication." msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "Não pode desativar a autenticação de dois fatores." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Não pode ativar a autenticação de dois factores enquanto não verificar o seu " "endereço de email." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "chave secreta" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Códigos de recuperação" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Autenticador TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Código do autenticador" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Palavra-passe" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Já existe uma conta com este endereço de email. Por favor, inicie a sessão " "com essa conta e depois associe a sua conta %s." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Código errado" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "A sua conta não tem uma palavra-passe definida." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "A sua conta não tem um endereço de email verificado." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third-party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "Pode iniciar a sessão usando uma das seguintes contas externas:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "A conta social já está conectada a uma outra conta diferente." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Contas de redes sociais" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "fornecedor" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID do fornecedor" #: socialaccount/models.py:56 msgid "name" msgstr "nome" #: socialaccount/models.py:58 msgid "client id" msgstr "ID do cliente" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID da aplicação ou chave do consumidor" #: socialaccount/models.py:63 msgid "secret key" msgstr "chave secreta" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "segredo da API, segredo do cliente ou segredo do consumidor" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Chave" #: socialaccount/models.py:81 msgid "social application" msgstr "aplicação social" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplicações sociais" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "último início de sessão" #: socialaccount/models.py:120 msgid "date joined" msgstr "data da inscrição" #: socialaccount/models.py:121 msgid "extra data" msgstr "dados extra" #: socialaccount/models.py:125 msgid "social account" msgstr "conta social" #: socialaccount/models.py:126 msgid "social accounts" msgstr "contas sociais" #: socialaccount/models.py:160 msgid "token" msgstr "código" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ou código de acesso (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "código secreto" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ou código de refrescamento (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "expira em" #: socialaccount/models.py:174 msgid "social application token" msgstr "código da aplicação social" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "códigos da aplicação social" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Dados de perfil inválidos" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Iniciar sessão" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Resposta inválida ao obter o código de requisição de \"%s\". A resposta foi: " "%s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Resposta inválida ao obter o código de acesso de \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Nenhum código de requisição gravado para \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Nenhum código de acesso gravado para \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Sem acesso a recursos privados em \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Resposta inválida ao obter o código de requisição de \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Conta desabilitada" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Esta conta está desabilitada." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Confirmar acesso" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "confirmação de email" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Introduza um código do autenticador:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Confirmar" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Iniciar sessão" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Endereços de email" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Os endereços de email seguintes estão associados à sua conta:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verificado" #: templates/account/email.html:29 msgid "Unverified" msgstr "Não verificado" #: templates/account/email.html:34 msgid "Primary" msgstr "Primário" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Torná-lo primário" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Re-enviar verificação" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Remover" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Adicionar endereço de email" #: templates/account/email.html:70 msgid "Add Email" msgstr "Adicionar email" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Deseja mesmo remover o endereço de email marcado?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Está a receber este email porque você, ou alguém,\n" "tentou criar uma conta usando o endereço de email:\n" "\n" "%(email)s\n" "\n" "No entanto já existe uma conta com este endereço de email.\n" "Caso se tenha esquecido disto, use o procedimento de recuperação\n" "de palavra-passe esquecida para recuperar a sua conta:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "A conta já existe" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Olá de %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Obrigado por usar %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Endereço de email" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Confirmou %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "confirmação de email" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Está a receber este email porque o utilizador %(user_display)s forneceu o " "seu endereço de email para criar uma conta em %(site_domain)s.\n" "\n" "Para confirmar que isto está certo, vá a %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Confirme o seu endereço de email" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Remover" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Iniciar sessão" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "A sua palavra-passe foi alterada." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Palavra-passe (novamente)" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Está a receber este email porque você, ou alguém, pediu para redefinir a " "palavra-passe da sua conta.\n" "Pode ignorar este email em segurança, caso não tenha feito tal pedido.\n" "Clique na ligação abaixo para redefinir a sua palavra-passe." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Caso se tenha esquecido, o seu nome de utilizador é %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Email com pedido de redefinição da palavra-passe" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "A sua palavra-passe foi alterada." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Redefinição da palavra-passe" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "A sua palavra-passe foi alterada." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Redefinição da palavra-passe" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "Contas" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Endereço de email" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Palavra-passe atual" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your email address is still pending verification:" msgid "Your email address is still pending verification." msgstr "O seu endereço de email ainda tem a verificação pendente:" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Change Email" msgid "Change to" msgstr "Alterar email" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Alterar email" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Confirmar endereço de email" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Por favor, confirme que %(email)s é um " "endereço de email do utilizador %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Não foi possível confirmar %(email)s porque já foi confirmado numa conta " "diferente." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Esta ligação de verificação de email expirou ou é inválida. Por favor, peça uma nova verificação de email.." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Se ainda não criou uma conta, então por favor %(link)sinscreva-" "se%(end_link)s primeiro." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Terminar sessão" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Tem certeza de que quer terminar a sessão?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Não pode remover o seu endereço de email primário (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Email de confirmação enviado para %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Confirmou %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Removeu o endereço de email %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Iniciou a sessão como %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Terminou a sessão." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Palavra-passe alterada com sucesso." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Palavra-passe definida com sucesso." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Endereço de email primário definido." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Alterar palavra-passe" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Esqueceu-se da sua palavra-passe?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Esqueceu-se da sua palavra-passe? Insira o seu endereço de email abaixo e " "enviar-lhe-emos um email para que a possa redefinir." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Redefinir a minha palavra-passe" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Contacte-nos se tiver dificuldades em redefinir a sua palavra-passe." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Enviámos-lhe um email. Se o não tiver recebido, verifique a pasta do spam. " "Se não o encontrar, contacte-nos, se não o receber dentro dos próximos " "minutos." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Código errado" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "A ligação para redefinir a palavra-passe era inválida, provavelmente por já " "ter sido usada. Faça um novo pedido para " "redefinir a palavra-passe." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "A sua palavra-passe foi alterada." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Definir palavra-passe" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Insira a sua palavra-passe:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 #, fuzzy #| msgid "Recovery Codes" msgid "Request Code" msgstr "Códigos de recuperação" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Inscrição" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Inscrever-se" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Já tem uma conta? Então %(link)sinicie a sessão%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Inscrever-se" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "As inscrições estão fechadas" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Lamentamos, mas as inscrições estão fechadas." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Nota" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Já tem a sessão iniciada como %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Aviso:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Neste momento não tem qualquer endereço de email definido. Devia mesmo " "adicionar um endereço de email para que possa receber notificações, " "redefinir a sua palavra-passe, etc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifique o seu endereço de email" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Enviámos-lhe um email para verificação. Siga a ligação fornecida para " "finalizar a inscrição. Se não encontrar o email de verificação na sua caixa " "de correio, verifique a pasta do spam. Contacte-nos se não receber o email " "de verificação nos próximos minutos." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Esta parte da aplicação requer que verifiquemos que\n" "você é quem diz ser. Para esse fim, pedimos que comprove\n" "ter a posse do seu endereço de email. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Enviámos-lhe um email para verificação.\n" "Clique na ligação que está nesse email.\n" "Se não encontrar o email de verificação na sua caixa de entrada, verifique a " "pasta do spam.\n" "Contacte-nos se não o receber dentro dos próximos minutos." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Nota: ainda pode alterar o seu " "endereço de email." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Mensagens:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Ligações da conta" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Autenticação de dois componentes" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "A sua conta está protegida por autenticação de dois factores. Insira o " "código do autenticador:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Foi gerado um novo conjunto de códigos de recuperação." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 #, fuzzy #| msgid "Recovery Codes" msgid "New Recovery Codes Generated" msgstr "Códigos de recuperação" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Autenticador habilitado." #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "Authenticator app activated." msgid "Authenticator App Activated" msgstr "Autenticador habilitado." #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Autenticador desabilitado." #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "Authenticator app deactivated." msgid "Authenticator App Deactivated" msgstr "Autenticador desabilitado." #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "Foi gerado um novo conjunto de códigos de recuperação." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Confirmou %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Autenticador" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "A autenticação usando um autenticador está habilitada." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Não há um autenticador habilitado." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Desabilitar" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Habilitar" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Códigos de recuperação" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Há %(unused_count)s código de recuperação disponível de um total de " "%(total_count)s." msgstr[1] "" "Há %(unused_count)s códigos de recuperação disponíveis de um total de " "%(total_count)s." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Não há códigos de recuperação definidos." #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "Descarregar" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Gerar" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Foi gerado um novo conjunto de códigos de recuperação." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Introduza um código do autenticador:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Está prestes a gerar um novo conjunto de códigos de recuperação para a sua " "conta." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Esta ação vai invalidar os seus códigos existentes." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Tem a certeza?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Códigos não utilizados" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Descarregar códigos" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Gerar novos códigos" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Habilitar autenticador" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Para proteger a sua conta com autenticação de dois fatores, digitalize o " "código QR abaixo com o seu autenticador. Depois, insira o código de " "verificação gerado pela aplicação, em baixo." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Segredo do autenticador" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Pode guardar este segredo e utilizá-lo para reinstalar o seu autenticador " "numa data posterior." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Desabilitar o autenticador" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Está prestes a desabilitar a autenticação baseada num autenticador. Tem a " "certeza?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "chave secreta" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "chave secreta" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Tem certeza de que quer terminar a sessão?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "chave secreta" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Não verificado" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "chave secreta" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Palavra-passe atual" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "criado" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Falha ao iniciar sessão com a conta de rede social" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Ocorreu um erro ao tentar iniciar sessão com a sua conta de rede social." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Pode iniciar a sessão usando uma das seguintes contas externas:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "De momento não tem nenhuma conta de rede social ligada a esta conta." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Adicionar uma conta externa" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a Third-Party Account" msgid "Third-Party Account Connected" msgstr "Adicionar uma conta externa" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a Third-Party Account" msgid "Third-Party Account Disconnected" msgstr "Adicionar uma conta externa" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Conectar %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Está prestes a conectar uma nova conta externa de %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Iniciar sessão via %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Está prestes a iniciar sessão usando uma conta externa de %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Continuar" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Início de sessão cancelado" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Você decidiu cancelar o início da sessão na nossa aplicação usando uma das " "suas contas existentes. Se o fez por engano, inicie a sessão." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "A conta social foi conectada." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "A conta social foi desconectada." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Está prestes a usar a sua conta %(provider_name)s para iniciar sessão em\n" "%(site_name)s. Para finalizar, por favor complete o seguinte formulário:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Address" msgid "IP Address" msgstr "Endereço de email" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Palavra-passe atual" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Ligações da conta" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "A palavra-passe tem que ter um mínimo de {0} caracteres." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Está a receber este email porque você, ou alguém, pediu uma palavra-passe " #~ "para a sua conta.\n" #~ "No entanto não temos qualquer registo de um utilizador com o endereço de " #~ "email\n" #~ "%(email)s na nossa base de dados.\n" #~ "\n" #~ "Este email pode ser ignorado em segurança se não fez tal pedido.\n" #~ "\n" #~ "Se foi você, pode criar uma conta usando a ligação abaixo." #~ msgid "The following email address is associated with your account:" #~ msgstr "O endereço de email seguinte está associado à sua conta:" #~ msgid "Change Email Address" #~ msgstr "Alterar endereço de email" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Por favor, inicie a sessão com uma\n" #~ "das suas contas externas. Ou então %(link)sinscreva-se\n" #~ "em %(site_name)s e inicie a sessão abaixo:" #~ msgid "or" #~ msgstr "ou" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "" #~ "Para salvaguardar a segurança da sua conta, insira a sua palavra-passe:" #~ msgid "OpenID Sign In" #~ msgstr "Iniciar sessão com OpenID" django-allauth-65.0.2/allauth/locale/ro/000077500000000000000000000000001467545753200200315ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ro/LC_MESSAGES/000077500000000000000000000000001467545753200216165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ro/LC_MESSAGES/django.po000066400000000000000000001511251467545753200234250ustar00rootroot00000000000000# DJANGO-ALLAUTH. # Copyright (C) 2016 # This file is distributed under the same license as the django-allauth package. # # Translators: # Steve Kossouho , 2016. # Gilou , 2019 # msgid "" msgstr "" "Project-Id-Version: django-allauthrr\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:34+0200\n" "Last-Translator: Gilou \n" "Language-Team: \n" "Language: ro_RO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && " "n%100<=19) ? 1 : 2);\n" "X-Generator: Poedit 3.0\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Acest cont este in prezent inactiv." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "" "Nu poti elimina adresa de e-mail (%(email)s). \n" "Aceasta este setata ca adresa principala de e-mail." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Aceasta adresa de e-mail este deja asociata acestui cont." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Adresa de e-mail si / sau parola sunt incorecte." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Un utilizator este deja inregistrat cu aceasta adresa de e-mail." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Te rugam tasteaza parola actuala." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Parola actuala" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Token invalid" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Link-ul de resetare a parolei nu era valid." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Nu poti adauga mai mult de %d adrese de e-mail." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Prea multe incercări de conectare esuate. Incearca mai tarziu." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Adresa de e-mail nu este atribuita niciunui cont de utilizator" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "" "Adresa de e-mail trebuie mai intai confirmata inainte de a o seta ca adresa " "principala. Acceseaza link-ul din e-mailul de verificare." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Numele de utilizator nu este disponibil. Te rugam alege alt nume de " "utilizator." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Numele de utilizator si / sau parola sunt incorecte." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Ai uitat parola?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "token secret" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "cheie secreta" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "" "Adresa de e-mail trebuie mai intai confirmata inainte de a o seta ca adresa " "principala. Acceseaza link-ul din e-mailul de verificare." #: account/apps.py:11 msgid "Accounts" msgstr "Conturi" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Trebuie sa tastezi aceeași parolă de fiecare data." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Parola" #: account/forms.py:93 msgid "Remember Me" msgstr "Tine-ma minte" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Adresa de e-mail" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Nume de utilizator" #: account/forms.py:123 msgid "Username or email" msgstr "Nume de utilizator sau e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Nume de utilizator sau e-mail" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Ai uitat parola?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (confirma)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Confirmarea adresei de e-mail" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (optional)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Trebuie sa tastezi aceeasi adresa de e-mail de fiecare data." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Parola (confirma)" #: account/forms.py:554 msgid "Current Password" msgstr "Parola actuala" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Parola noua" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Parola noua (confirma)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "utilizator" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "adresa de e-mail" #: account/models.py:34 msgid "verified" msgstr "verificata" #: account/models.py:35 msgid "primary" msgstr "principala" #: account/models.py:41 msgid "email addresses" msgstr "adrese de e-mail" #: account/models.py:150 msgid "created" msgstr "creata" #: account/models.py:151 msgid "sent" msgstr "trimis" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "cheie" #: account/models.py:157 msgid "email confirmation" msgstr "confirmare e-mail" #: account/models.py:158 msgid "email confirmations" msgstr "confirmari e-mail" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "cheie secreta" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Parola" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Exista deja un cont cu această adresa de e-mail. Te rugam sa vt conectați " "mai intai la acel cont, apoi sa conecteazi contul %s." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Token invalid" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Contul tau nu are o parola setata." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Contul tau nu are o adresa de e-mail confirmata." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Te poti conecta la contul tau folosind oricare dintre urmatoarele conturi de " "socializare (conturi terte):" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "" "Acest cont de socializare este deja asociat unui alt profil pe site-ul " "nostru." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Retele de socializare" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "furnizor" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "furnizor" #: socialaccount/models.py:56 msgid "name" msgstr "nume" #: socialaccount/models.py:58 msgid "client id" msgstr "id client" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID-ul aplicatiei sau cheia consumatorului" #: socialaccount/models.py:63 msgid "secret key" msgstr "cheie secreta" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API secret, client secret sau consumator secret" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Cheie" #: socialaccount/models.py:81 msgid "social application" msgstr "aplicatie sociala" #: socialaccount/models.py:82 msgid "social applications" msgstr "aplicatii sociale" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "ultima logare" #: socialaccount/models.py:120 msgid "date joined" msgstr "data inscrierii" #: socialaccount/models.py:121 msgid "extra data" msgstr "date suplimentare" #: socialaccount/models.py:125 msgid "social account" msgstr "retea de socializare" #: socialaccount/models.py:126 msgid "social accounts" msgstr "retele de socializare" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) sau token de acces (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token secret" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) token de reimprospatare (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "expira la" #: socialaccount/models.py:174 msgid "social application token" msgstr "token pentru aplicatia de socializare" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "token-uri pentru aplicatiile de socializare" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Date de profil invalide" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Nume de utilizator sau e-mail" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Raspuns invalid la obtinerea token-ului de solicitare de la \"% s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Raspuns invalid la obtinerea token-ului de acces de la \"% s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Nu s-a salvat niciun token de solicitare pentru \"% s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Nu s-a salvat niciun token de acces pentru \"% s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Nu exista acces la resurse private la \"% s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Raspuns invalid la obtinerea token-ului de solicitare de la \"% s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Cont inactiv" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Acest cont este inactiv." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Confirma adresa de e-mail" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "confirmare e-mail" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "token secret" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Confirma" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Conecteaza-te" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Adrese de e-mail" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Urmatoarele adrese de e-mail sunt asociate contului tau:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verificata" #: templates/account/email.html:29 msgid "Unverified" msgstr "Neverificata" #: templates/account/email.html:34 msgid "Primary" msgstr "Principala" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Seteaza ca principala" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Retrimite e-mail verificare" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Elimina adresa" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Adauga adresa de e-mail" #: templates/account/email.html:70 msgid "Add Email" msgstr "Adauga e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Sigur doresti sa elimini aceasta adresa de e-mail?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Salutari de la %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Iti multumim ca folosesti %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Adresa de e-mail" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Ai confirmat %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "confirmare e-mail" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Ai primit acest e-mail pentru ca utilizatorul %(user_display)s a folosit " "aceasta adresa de e-mail pentru a inregistra un cont pe %(site_domain)s.\n" "\n" "Pentru a confirma, click pe link-ul urmator: %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Te rugam confirma adresa de e-mail" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Elimina adresa" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Conecteaza-te" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Parola ta a fost schimbata cu succes." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Parola (confirma)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Ai primit acest e-mail pentru ca tu sau altcineva a solicitat o resetare de " "parola.\n" "Daca nu ai fost tu cel care a solicitat resetarea parolei, te rugam sa " "ignori acest e-mail.\n" "Pentru resetarea parolei acceseaza linkul de mai jos." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "In cazul in care ai uitat, numele tau de utilizator este %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail pentru resetarea parolei" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Parola ta a fost schimbata cu succes." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Reseteaza parola" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Parola ta a fost schimbata cu succes." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Reseteaza parola" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Compte" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Adrese de e-mail" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Parola actuala" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "" "Adresa de e-mail trebuie mai intai confirmata inainte de a o seta ca adresa " "principala. Acceseaza link-ul din e-mailul de verificare." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Confirma adresa de e-mail" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Te rugam confirma faptul ca %(email)s este " "o adresa de e-mail a utilizatorului %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Acest cont de socializare este deja asociat unui alt profil pe site-ul " "nostru." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Link-ul de confirmare a adresei de email a expirat sau este invalid. Te " "rugam solicita un nou link de confirmare." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Daca nu ai un cont inca, te rugam %(link)sinregistreaza-te%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Deconecteaza-te" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Esti sigur(a) ca vrei sa te deconectezi?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "" "Nu poti elimina adresa de e-mail (%(email)s). \n" "Aceasta este setata ca adresa principala de e-mail." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Confirma e-mailul trimis catre %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Ai confirmat %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Adresa de e-mail eliminata %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Esti conectat(a) ca %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Te-ai deconectat." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Parola a fost schimbata cu success." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Parola a fost setata cu success." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Adresa principala de e-mail a fost setata." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Schimba parola" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Ai uitat parola?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Ti-ai uitat parola? Introdu adresa de e-mail mai jos si-ti vom trimite un e-" "mail ce-ti va permite sa resetezi parola." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Reseteaza parola" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Te rugam contacteaza-ne daca intampini dificultati in resetarea parolei." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Ti-am trimis un e-mail pentru verificare (confirmare). \n" "Acceseaza link-ul din e-mail pentru confirmare. \n" "Te rugam contacteaza-ne daca nu primesti e-mailul in cateva minute." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Token invalid" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Link-ul de resetare a parolei este invalid, posibil din cauza ca a fost deja " "folosit. Te rugam solicita un nou link de " "resetare a parolei." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Parola ta a fost schimbata cu succes." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Seteaza parola" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Ai uitat parola?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Inregistrare" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Inregistreaza-te" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Ai deja un cont? Te rugam %(link)sconecteaza-te%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Inregistreaza-te" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Inregistrare blocata" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Ne pare rau, posibilitatea inregistrarii este momentan blocata." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Nota" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "esti deja conectat ca %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Avertizare:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "În prezent nu ai configurata nicio adresa de e-mail. Adauga o adresa de e-" "mail pentru a primi notificari, a putea reseta parola, etc." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifica-ti adresa de e-mail" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Ti-am trimis un e-mail pentru verificare (confirmare). Acceseaza link-ul din " "e-mail pentru a finaliza procesul de inregistrare. Te rugam contacteaza-ne " "daca nu primesti e-mailul in cateva minute." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Pentru a accesa aceasta sectiune a site-ului \n" "te rugam sa confirmi ca aceasta adresa de e-mail iti apartine. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Ti-am trimis un e-mail pentru verificare (confirmare). \n" "Acceseaza link-ul din e-mail pentru confirmare. \n" "Te rugam contacteaza-ne daca nu primesti e-mailul in cateva minute." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Nota: poti in continuarea sa-ti " "schimbi adresa de e-mail." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Conexiuni" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "token secret" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "token secret" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Ai confirmat %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "token secret" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "token secret" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "cheie secreta" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "cheie secreta" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Esti sigur(a) ca vrei sa te deconectezi?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "cheie secreta" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Neverificata" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "cheie secreta" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Parola actuala" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "creata" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Conectarea la reteaua sociala a esuat" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "A aparut o eroare in incercarea de a te autentifica folosind aceasta cont de " "retea sociala." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Te poti conecta la contul tau folosind oricare dintre urmatoarele conturi de " "socializare (conturi terte):" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "In present nu ai niciun cont de retea sociala asociat cu acest cont." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Adauga un cont de retea sociala" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Adauga un cont de retea sociala" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Adauga un cont de retea sociala" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Conectare anulata" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Ai decis sa anulezi procesul de conectare la contul tau. Daca ai anulat din " "greseala, te rugam acceseaza link-ul conecteaza-te " "la contul tau." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Contul a fost conectat cu success." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Contul de socializare a fost deconectat." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Esti pe cale de a folosi contul %(provider_name)s pentru a te conecta la\n" "%(site_name)s. Pentru finalizarea procesului, te rugam completeaza urmatorul " "formular:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Adrese de e-mail" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Parola actuala" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Conexiuni" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Parola trebuie să aibă minimum {0} caractere." #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Ai primit acest e-mail pentru ca tu sau altcineva a solicitat o resetare " #~ "de parola.\n" #~ "Daca nu ai fost tu cel care a solicitat resetarea parolei, te rugam sa " #~ "ignori acest e-mail.\n" #~ "Pentru resetarea parolei acceseaza linkul de mai jos." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Urmatoarele adrese de e-mail sunt asociate contului tau:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Confirma adresa de e-mail" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Te rugam conecteaza-te cu unul\n" #~ "din conturile de mai jos. Sau %(link)screeaza un cont\n" #~ "%(site_name)s si apoi conecteaza-te folosind formularul de mai jos:" #~ msgid "or" #~ msgstr "sau" #~ msgid "change password" #~ msgstr "schimba parola" #~ msgid "OpenID Sign In" #~ msgstr "Conectare OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Aceasta adresa de e-mail este deja asociata altui cont." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Ti-am trimis un e-mail. Daca nu-l gasesti in \"inbox\", te rugam verifica " #~ "si folderul \"spam\".\n" #~ "Te rugam contacteaza-ne daca nu-l primesti in cateva minute." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "L'identifiant ou le mot de passe sont incorrects." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Un pseudonyme ne peut contenir que des lettres, des chiffres, ainsi que " #~ "@/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Ce pseudonyme est déjà utilisé, merci d'en choisir un autre." #~ msgid "Shopify Sign In" #~ msgstr "Connexion Shopify" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Vous avez confirmé que l'adresse e-mail de l'utilsateur %(user_display)s " #~ "est %(email)s." #~ msgid "Thanks for using our site!" #~ msgstr "Merci d'utiliser notre site !" django-allauth-65.0.2/allauth/locale/ru/000077500000000000000000000000001467545753200200375ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ru/LC_MESSAGES/000077500000000000000000000000001467545753200216245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/ru/LC_MESSAGES/django.po000066400000000000000000002000211467545753200234210ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-06-18 13:09+0000\n" "Last-Translator: Andrei Satsevich \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || " "(n%100>=11 && n%100<=14)? 2 : 3);\n" "X-Generator: Weblate 5.6-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Учетная запись неактивна." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Вы не можете удалить свой основной адрес электронной почты." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Этот адрес электронной почты уже связан с этой учетной записью." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Указанные вами адрес электронной почты и/или пароль неверны." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Пользователь с таким адресом электронной почты уже зарегистрирован." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Пожалуйста, введите свой текущий пароль." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Неверный код." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Неверный пароль." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Недействительный или просроченный ключ." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Код сброса пароля оказался недействительным." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Вы не можете добавить более %d адресов электронной почты." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Слишком много неудачных попыток входа в систему. Повторите попытку позже." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Адрес электронной почты не закреплен ни за одной учетной записью" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Ваш основной адрес электронной почты должен быть подтвержден." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Такое имя пользователя не может быть использовано, выберите другое." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Имя пользователя и/или пароль неверны." #: account/adapter.py:741 msgid "Use your password" msgstr "Используйте ваш пароль" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "Используйте приложение-аутентификатор" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "секретный ключ" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Отметить выбранные адреса электронной почты как подтверждённые" #: account/apps.py:11 msgid "Accounts" msgstr "Аккаунты" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Вы должны ввести одинаковый пароль дважды." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Пароль" #: account/forms.py:93 msgid "Remember Me" msgstr "Запомнить меня" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Адрес электронной почты" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Имя пользователя" #: account/forms.py:123 msgid "Username or email" msgstr "Имя пользователя или e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Войти" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Забыли свой пароль?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (ещё раз)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Подтверждение адреса электронной почты" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (опционально)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Вы должны ввести одинаковый e-mail дважды." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Пароль (ещё раз)" #: account/forms.py:554 msgid "Current Password" msgstr "Текущий пароль" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Новый пароль" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Новый пароль (ещё раз)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Код" #: account/models.py:26 msgid "user" msgstr "пользователь" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "адрес электронной почты" #: account/models.py:34 msgid "verified" msgstr "подтвержден" #: account/models.py:35 msgid "primary" msgstr "основной" #: account/models.py:41 msgid "email addresses" msgstr "адреса электронной почты" #: account/models.py:150 msgid "created" msgstr "создано" #: account/models.py:151 msgid "sent" msgstr "отправлено" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "ключ" #: account/models.py:157 msgid "email confirmation" msgstr "подтверждение email адреса" #: account/models.py:158 msgid "email confirmations" msgstr "подтверждения email адресов" #: headless/apps.py:7 msgid "Headless" msgstr "Безголовый" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Вы не можете добавить адрес электронной почты в учетную запись, защищенную " "двухфакторной аутентификацией." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Вы не можете отключить двухфакторную аутентификацию." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Вы не можете генерировать коды восстановления, если не включена " "двухфакторная аутентификация." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Вы не сможете активировать двухфакторную аутентификацию, пока не пдотвердите " "свой адрес электронной почты." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "секретный ключ" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "Многофакторная аутентификация (MFA)" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Коды восстановления" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Аутентификатор TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Код аутентификатора" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Пароль" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Учетная запись с таким адресом электронной почты уже существует.Пожалуйста, " "сначала войдите в эту учетную запись, а затем подключите %s." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Недействительный токен." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Для вашего аккаунта не установлен пароль." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "В вашей учетной записи нет подтвержденного адреса электронной почты." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Вы не можете отключить свою последнюю оставшуюся стороннюю учетную запись." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "" "Учетная запись стороннего сервиса уже подключена к другой учетной записи." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Аккаунты в социальных сетях" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "провайдер" #: socialaccount/models.py:52 msgid "provider ID" msgstr "провайдер ID" #: socialaccount/models.py:56 msgid "name" msgstr "имя" #: socialaccount/models.py:58 msgid "client id" msgstr "id клиента" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID приложения или ключ потребителя" #: socialaccount/models.py:63 msgid "secret key" msgstr "секретный ключ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Секретный ключ API, клиента или потребителя" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Ключ" #: socialaccount/models.py:81 msgid "social application" msgstr "социальное приложение" #: socialaccount/models.py:82 msgid "social applications" msgstr "социальные приложения" #: socialaccount/models.py:117 msgid "uid" msgstr "UID пользователя" #: socialaccount/models.py:119 msgid "last login" msgstr "дата последнего входа в систему" #: socialaccount/models.py:120 msgid "date joined" msgstr "дата регистрации" #: socialaccount/models.py:121 msgid "extra data" msgstr "дополнительные данные" #: socialaccount/models.py:125 msgid "social account" msgstr "аккаунт социальной сети" #: socialaccount/models.py:126 msgid "social accounts" msgstr "аккаунты социальных сетей" #: socialaccount/models.py:160 msgid "token" msgstr "токен" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) или access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "секретный токен" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) или refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "истекает" #: socialaccount/models.py:174 msgid "social application token" msgstr "токен социального приложения" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "токены социальных приложений" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Неверные данные профиля" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Вход" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Отмена" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Неверный ответ во время получения запроса от \"%s\". Ответ был: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Неверный ответ при получении токена доступа от \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Нет сохраненного ключа запроса для \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Нет сохраненного ключа доступа для \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Доступ к ресурсам закрыт \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Неверный ответ во время получения запроса от \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Аккаунт неактивен" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Этот аккаунт неактивен." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Подтвердите доступ" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" "Пожалуйста, пройдите повторную аутентификацию, чтобы обезопасить свою " "учетную запись." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Альтернативные варианты" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "Подтверждение по электронной почте" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Введите код аутентификатора:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Мы отправили код на адрес %(email_link)s. Срок действия кода скоро истечет, " "поэтому, пожалуйста, введите его как можно скорее." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Подтвердить" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Войти" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Введите код для входа в систему" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Адреса электронной почты" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "С вашей учетной записью связаны следующие адреса электронной почты:" #: templates/account/email.html:25 msgid "Verified" msgstr "Подтвержден" #: templates/account/email.html:29 msgid "Unverified" msgstr "Не подтвержден" #: templates/account/email.html:34 msgid "Primary" msgstr "Основной" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Сделать основным" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Отправить подтверждение ещё раз" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Удалить" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Добавить адрес электронной почты" #: templates/account/email.html:70 msgid "Add Email" msgstr "Добавить E-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Вы действительно хотите удалить выбранный адрес электронной почты?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Вы получили это письмо, потому что вы или кто-то другой пытались " "зарегистрировать учетную запись, используя адрес электронной почты: \n" "%(email)s\n" "\n" "Однако учетная запись с таким адресом электронной почты уже существует. В " "случае, если вы вы забыли об этом, воспользуйтесь процедурой \"Забыли " "пароль\", чтобы восстановить свою учетную запись: \n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Учетная запись уже существует" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Вас приветствует %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Благодарим вас за использование сайта «%(site_name)s!»\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Вы получили это письмо, потому что в вашей учетной записи были сделаны " "следующие изменения:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Если вы не заметили этого изменения, пожалуйста, немедленно примите " "надлежащие меры безопасности. Изменения в вашей учетной записи произошли с:\n" "\n" "- IP-адреса: %(ip)s\n" "- Браузера: %(user_agent)s\n" "- Дата: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" "Ваш адрес электронной почты был изменен с %(from_email)s на %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Электронная почта изменена" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Ваш адрес электронной почты был подтвержден." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Подтверждение по электронной почте" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Вы получили это письмо, потому что пользователь %(user_display)s указал ваш " "адрес электронной почты для регистрации учетной записи на сайте " "%(site_domain)s.\n" "\n" "Чтобы подтвердить, перейдите по ссылке %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Ваш регистрационный код указан ниже. Пожалуйста, введите его в открытом окне " "вашего браузера." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Пожалуйста, подтвердите Ваш адрес электронной почты" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" "Адрес электронной почты %(deleted_email)s был удалён из вашей учётной записи" #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Email удалён" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Ваш регистрационный код указан ниже. Пожалуйста, введите его в открытом окне " "вашего браузера." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Это письмо можно спокойно проигнорировать, если вы не инициировали это " "действие." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Код для входа" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Ваш пароль изменён." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Пароль Изменён" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Вы получили это письмо, потому что вы или кто-то другой запросили сброс " "пароля для вашей учетной записи.\n" "Если это были не вы, просто проигнорируйте это письмо. Нажмите на ссылку " "ниже, чтобы сбросить пароль." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Если вы вдруг забыли, ваше имя пользователя: %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Письмо для сброса пароля" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Ваш пароль был сброшен." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Сброс пароля" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Ваш пароль был установлен." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Пароль Установлен" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Вы получили это электронное письмо, потому что вы или кто-то другой пытался " "получить доступ к учетной записи с помощью электронной почты %(email)s. " "Однако в нашей базе данных нет никаких записей о такой учетной записи." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Если это были вы, вы можете зарегистрировать учетную запись, перейдя по " "ссылке ниже." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Неизвестный аккаунт" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Адрес электронной почты" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Текущий e-mail" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Изменить на" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Ваш адрес электронной почты ожидает подтверждения." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Отменить изменения" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Изменить на" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Изменить E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Подтвердите адрес электронной почты" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Пожалуйста, подтвердите %(email)s для " "пользователя %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Невозможно подтвердить %(email)s, потому что он уже прикреплен к другой " "учетной записи." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Ссылка некорректна или срок её действия истек. Пожалуйста, отправьте новый запрос на подтверждение электронной " "почты." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Если у вас ещё нет учётной записи, пожалуйста, сначала " "%(link)sзарегистрируйтесь%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Пришлите мне код для входа" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Выйти" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Вы уверены, что хотите выйти?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "" "Вы не можете удалить свой основной адрес электронной почты (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Подтверждающее письмо отправлено на %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Адрес %(email)s подтверждён." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Удален адрес электронной почты %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Успешный вход под именем %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Вы вышли." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Код для входа был отправлен по электронной почте на адрес %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Пароль успешно изменён." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Пароль успешно установлен." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Установлен основной адрес электронной почты" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Изменить пароль" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Забыли пароль?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Забыли свой пароль? Введите Ваш адрес электронной почты ниже, и мы отправим " "Вам письмо, чтобы вы могли его сбросить." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Сбросить мой пароль" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "Свяжитесь с нами, если у вас возникли сложности со сменой пароля." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Мы отправили вам письмо. Если вы его не получили, проверьте папку \"Спам\". " "Свяжитесь с нами, если вы не получили письмо в течение нескольких минут." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Неправильный ключ" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Ссылка на сброс пароля неверна, вероятно, она уже была использована. Для " "нового сброса пароля перейдите по ссылке." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Ваш пароль изменён." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Установить пароль" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Введите пароль:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Вы получите электронное письмо, содержащее специальный код для входа в " "систему без пароля." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Код запроса" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Другие варианты входа" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Регистрация" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Регистрация" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Уже зарегистрированы? %(link)sВойдите%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Регистрация" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Другие варианты входа" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Регистрация закрыта" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Мы сожалеем, но в текущий момент регистрация закрыта." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Заметка" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Вы уже вошли как %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Внимание:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Сейчас у вас нет прикрепленного адрес электронной почты. Рекомендуем " "добавить, чтобы иметь возможность получать уведомления, сбрасывать пароль и " "и т.д." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Подтвердите Ваш адрес электронной почты" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Мы отправили вам письмо с подтверждением. Перейдите по указанной ссылке, " "чтобы завершить процесс регистрации. Если вы не видите письмо с " "подтверждением в вашем основном почтовом ящике, проверьте папку \"Спам\"." "Пожалуйста, свяжитесь с нами, если вы не получите письмо с подтверждением в " "течение нескольких минут." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Эта часть сайта требует от нас подтверждения того, что вы являетесь тем, за " "кого себя выдаете. Для этого нам необходимо подтвердить собственность вашего " "адреса электронной почты." #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Мы отправили вам письмо\n" "для проверки. Пожалуйста, перейдите по ссылке. Если вы не видите письмо с " "подтверждением в вашем основном почтовом ящике, проверьте папку \"Спам\".В " "противном случае свяжитесь с нами, если вы не получите его в течение " "нескольких минут." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Заметка: вы можете изменить свой " "адрес электронной почты." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Сообщения:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Меню:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Прикрепленные аккаунты" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Двухфакторная аутентификация" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Сеансы" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Ваша учетная запись защищена двухфакторной аутентификацией. Пожалуйста, " "введите код аутентификатора:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "Сгенерирован новый набор кодов восстановления двухфакторной аутентификации." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Сгенерированы Новые Коды Восстановления" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Активировано приложение Аутентификатор." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Активировано приложение для проверки подлинности" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Приложение Аутентификатор деактивировано." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Приложение для проверки подлинности отключено" #: templates/mfa/email/webauthn_added_message.txt:4 #, fuzzy #| msgid "A new set of recovery codes has been generated." msgid "A new security key has been added." msgstr "Был создан новый набор кодов восстановления." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your email has been confirmed." msgid "A security key has been removed." msgstr "Ваш адрес электронной почты был подтвержден." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Приложение аутентификатор" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Аутентификация с помощью приложения-аутентификатора активна." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Приложение аутентификатора неактивно." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Деактивировать" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Активировать" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Коды восстановления" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "Доступно %(unused_count)s из %(total_count)s кодов восстановления." msgstr[1] "Доступнен %(unused_count)s из %(total_count)s кодов восстановления." msgstr[2] "Доступны %(unused_count)s из %(total_count)s кодов восстановления." msgstr[3] "Доступны %(unused_count)s из %(total_count)s кодов восстановления." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Коды восстановления не установлены." #: templates/mfa/index.html:96 msgid "View" msgstr "Посмотреть" #: templates/mfa/index.html:102 msgid "Download" msgstr "Скачать" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Генерировать" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Был создан новый набор кодов восстановления." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Введите код аутентификатора:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Вы собираетесь сгенерировать новый набор кодов восстановления для вашей " "учетной записи." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Это действие аннулирует существующие коды." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Вы уверены?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Неиспользуемые коды" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Скачать коды" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Генерировать новые коды" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Активировать приложение Аутентификатор" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Чтобы защитить свою учетную запись с помощью двухфакторной аутентификации, " "отсканируйте приведенный ниже QR-код с помощью приложения-аутентификатора. " "Затем введите проверочный код, сгенерированный приложением ниже." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Код аутентификатора" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Вы можете сохранить этот секрет ключ и использовать его для повторной " "установки приложения аутентификатора в будущем." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Отключите приложение Аутентификатор" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Вы собираетесь отключить аутентификацию с использованием приложения " "Аутентификатор. Вы уверены?" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "секретный ключ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "секретный ключ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Вы уверены, что хотите выйти?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "секретный ключ" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Не подтвержден" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "секретный ключ" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Текущий пароль" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "создано" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Ошибка входа через внешний сервис" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "При попытке войти через учетную запись стороннего сервиса произошла ошибка." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Вы можете авторизоваться, используя следующие сервисы:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "" "В настоящее время у вас нет учетных записей сторонних сервисов, связанных с " "этой учетной записью." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Добавить внешний аккаунт" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "К вашей учетной записи была подключена сторонняя учетная запись от " "%(provider)s." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Подключена учетная запись стороннего сервиса" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "Сторонняя учетная запись от %(provider)s была отключена от вашей учетной " "записи." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Учетная запись стороннего сервиса отключена" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Соединение с %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Вы собираетесь подключить новый сторонний аккаунт из %(provider)s" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Вход через %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Вы собираетесь войти, используя стороннюю учетную запись из %(provider)s" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Продолжить" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Авторизация отменена" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Вы прервали авторизацию, используя один из ваших аккаутов. Если это было " "ошибкой, перейдите к авторизации. " #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Учетная запись стороннего сервиса подключена." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Сторонняя учетная запись была отключена." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Вы используете %(provider_name)s для авторизации на \n" "%(site_name)s. Чтобы завершить, заполните следующую форму:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Или использовать сторонний" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Выйти из всех остальных сеансов." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Начато в" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP-адрес" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Браузер" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Последний вход в" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Текущий" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Выйти из других сеансов" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Сеансы пользователей" #: usersessions/models.py:92 msgid "session key" msgstr "ключ сеанса" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Прикрепленные аккаунты" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Минимальное количество символов в пароле: {0}." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Вы получили это письмо, потому что вы или кто-то другой запросили сброс " #~ "пароля для вашей учетной записи.Однако нашей базе данных ничего не " #~ "известно о пользователес электронной почтой %(email)s.\n" #~ "\n" #~ "Если это были не вы, просто проигнорируйте это письмо.\n" #~ "Если же это всё-таки были вы, вы можете зарегистрировать аккаунт по " #~ "ссылке ниже." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Следующие e-mail адреса прикреплены к вашему аккаунту:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Подтвердите e-mail адрес." #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Пожалуйста, войдите с одним\n" #~ "из ваших внешних аккаунтов. Или зарегистрируйтесь\n" #~ "и авторизуйтесь на сайте %(site_name)s:" #~ msgid "or" #~ msgstr "или" #~ msgid "change password" #~ msgstr "изменить пароль" #~ msgid "OpenID Sign In" #~ msgstr "Войти с OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Указанный e-mail прикреплен к другому пользователю." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Мы отправили вам письмо. Пожалуйста, свяжитесь с нами, если не получили " #~ "его в течение нескольких минут." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Логин и/или пароль не верны." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "Имя пользователя может включать буквы, цифры и @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "" #~ "Такое имя пользователя уже используется на сайте. Пожалуйста выберите " #~ "другое." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Войти" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Вы подтвердили адрес %(email)s для " #~ "пользователя %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "Спасибо за использование нашего сайта!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Подтверждение выслано на %(email)s" #~ msgid "Delete Password" #~ msgstr "Удалить пароль" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "Вы можете удалить свой пароль, при использовании OpenID." #~ msgid "delete my password" #~ msgstr "удалите мой пароль" #~ msgid "Password Deleted" #~ msgstr "Пароль удалён" django-allauth-65.0.2/allauth/locale/sk/000077500000000000000000000000001467545753200200265ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sk/LC_MESSAGES/000077500000000000000000000000001467545753200216135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sk/LC_MESSAGES/django.po000066400000000000000000001500051467545753200234160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-08-29 07:21+0000\n" "Last-Translator: Adam Zahradník \n" "Language-Team: Slovak \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n " ">= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n" "X-Generator: Weblate 5.7.1-dev\n" "X-Translated-Using: django-rosetta 0.9.9\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Tento účet nie je momentálne aktívny." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Primárna e-mailová adresa sa nedá odstrániť." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Táto e-mailová adresa je už spojená s týmto účtom." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Uvedený e-mail alebo heslo nie je správne." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Používateľ s touto e-mailovou adresou už existuje." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Prosím, napíšte svoje súčasné heslo." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Nesprávny kód." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Nesprávne heslo." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Neplatný kľúč." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Token na obnovu hesla bol nesprávny." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Nemôžte pridať viac než %d e-mailových adries." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Príliš veľa neúspešných pokusov o prihlásenie. Skúste neskôr." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "" "Táto e-mailová adresa nie je pridelená k žiadnemu používateľskému kontu" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Primárna e-mailová adresa musí byť overená." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Užívateľské meno nemôže byť použité. Prosím, použite iné meno." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Uvedené užívateľské meno alebo heslo nie je správne." #: account/adapter.py:741 msgid "Use your password" msgstr "Použite svoje heslo" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Použiť autentifikačnú aplikáciu alebo kód" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Použiť bezpečnostný kľuč" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Označiť vybrané adresy ako overené" #: account/apps.py:11 msgid "Accounts" msgstr "Účty" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Heslá sa nezhodujú." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Heslo" #: account/forms.py:93 msgid "Remember Me" msgstr "Zapamätať si ma" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-mailová adresa" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-mail" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Užívateľské meno" #: account/forms.py:123 msgid "Username or email" msgstr "Užívateľské meno alebo e-mail" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Login" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Zabudnuté heslo?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-mail (znova)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Potvrdenie e-mailu" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-mail (nepovinné)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "E-maily sa nezhodujú." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Heslo (znovu)" #: account/forms.py:554 msgid "Current Password" msgstr "Súčasné heslo" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nové heslo" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nové heslo (znovu)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kód" #: account/models.py:26 msgid "user" msgstr "používateľ" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-mailová adresa" #: account/models.py:34 msgid "verified" msgstr "overený" #: account/models.py:35 msgid "primary" msgstr "primárny" #: account/models.py:41 msgid "email addresses" msgstr "e-mailové adresy" #: account/models.py:150 msgid "created" msgstr "vytvorený" #: account/models.py:151 msgid "sent" msgstr "odoslané" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "kľúč" #: account/models.py:157 msgid "email confirmation" msgstr "potvrdenie e-mailu" #: account/models.py:158 msgid "email confirmations" msgstr "potvrdenia e-mailu" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Nemôžete si pridať ďalšiu emailovú adresu do účtu s dvojfaktorovou " "autentifikáciou." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Nemôžete si deaktivovať dvojfaktorovú autentifikáciu." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Nemôžete si vygenerovať záložné kódy bez aktívnej dvojfaktorovej " "autentifikácie." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Nemôžete aktivovať dvojfaktorovú autentifikáciu pokiaľ nemáte verifikovanú " "svoju adresu." #: mfa/adapter.py:141 msgid "Master key" msgstr "Hlavný kľúč" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Záložný kľúč" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Kľúč č. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Kódy obnovy" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP autentifikátor" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Kód z autentifikátora" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Prihlásenie bez hesla" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Aktivácia prihlásenia bez hesla vám dovolí prihlásiť sa len pomocou tohto " "kľúča, ale vyžaduje dodatočné požiadavky ako napríklad PIN alebo biometriu." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Účet s touto e-mailovou adresou už existuje. Prosím, prihláste sa najprv pod " "daným účtom a potom pripojte svoj %s účet." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Neplatný token." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Váš účet nemá nastavené heslo." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Váš účet nemá overenú e-mailovú adresu." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Nemôžete si odstrániť svoj posledný účet tretej strany." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Tento účet tretej strany už je priradený k inému používateľovi." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Účty na sociálnych sieťach" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "poskytovateľ" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ID poskytovateľa" #: socialaccount/models.py:56 msgid "name" msgstr "meno" #: socialaccount/models.py:58 msgid "client id" msgstr "identifikátor klienta" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID aplikácie alebo zákaznícky kľúč" #: socialaccount/models.py:63 msgid "secret key" msgstr "tajný kľúč" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Kľúč API, klienta alebo zákazníka" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Kľúč" #: socialaccount/models.py:81 msgid "social application" msgstr "sociálna aplikácia" #: socialaccount/models.py:82 msgid "social applications" msgstr "sociálne aplikácie" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "posledné prihlásenie" #: socialaccount/models.py:120 msgid "date joined" msgstr "dáum pripojenia" #: socialaccount/models.py:121 msgid "extra data" msgstr "ďalšie údaje" #: socialaccount/models.py:125 msgid "social account" msgstr "sociálny účet" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sociálne účty" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" "\"Oauth_token\" (Podpora protokolu OAuth1) alebo prístup tokenu (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "heslo prístupového tokenu" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" "\"Oauth_token_secret\" (Podpora protokolu OAuth1) alebo token obnovenie " "(OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "vyexpiruje" #: socialaccount/models.py:174 msgid "social application token" msgstr "token sociálnej aplikácie" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokeny sociálnej aplikácie" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Nesprávne profilové údaje" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Prihlásiť sa" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Zrušiť" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Neplatná odpoveď pri získavaní request tokenu z \"%s\". Odpoveď: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Neplatná odozva pri získavaní prístupu tokenu z \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Žiadna uložená požiadavka tokenu pre \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Žiadny uložený prístupový token pre \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Žiadny prístup do privátneho úložiska na \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Neplatná odpoveď pri získavaní request tokenu z \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Účet neaktívny" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Tento účet je neaktívny." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Potvrdiť prístup" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Znova sa overte, aby ste ochránili svoj účet." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Alternatívne možnosti" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "Overenie emailovej adresy" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Zadajte kód na overenie emailovej adresy" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Odoslali sme overovací kód na adresu %(email_link)s. Platnosť tohto kódu " "čoskoro vyprší, zadajte ho čo najskôr." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Potvrdiť" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Prihlásiť sa" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Zadanie prihlasovacieho kódu" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-mailová adresa" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Nasledujúce e-mailové adresy sú prepojené s vašim účtom:" #: templates/account/email.html:25 msgid "Verified" msgstr "Overený" #: templates/account/email.html:29 msgid "Unverified" msgstr "Neoverený" #: templates/account/email.html:34 msgid "Primary" msgstr "Primárny" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Vytvoriť primárny" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Preposlať overenie" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Odstrániť" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Pridať e-mailovú adresu" #: templates/account/email.html:70 msgid "Add Email" msgstr "Pridať e-mail" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Naozaj chcete odstrániť vybranú e-mailovú adresu?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Tento e-mail ste dostali, pretože ste sa vy, alebo niekto iný\n" "pokúšali vytvoriť účet pre e-mailovu adresu:\n" "\n" "%(email)s\n" "\n" "Účet s touto e-mailovou adresou už však existuje. V prípade,\n" "že ste na svoju registráciu zabudli, použite prosím funkciu obnovy\n" "hesla vášho účtu:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Účet už existuje" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Dobrý deň z %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Ďakujeme za využitie %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Tento email dostávate kvôli nasledujúcim zmenám vo vašom účte:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Ak ste tieto zmeny nevykonali vy, prosím okamžite prijmite náležité " "bezpečnostné opatrenia. Zmeny vo vašom účte pochádzajú z:\n" "\n" "- IP adresa: %(ip)s\n" "- Prehliadač: %(user_agent)s\n" "- Dátum: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Vaša emailová adresa bola zmenená z %(from_email)s na %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Emailová adresa zmenená" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Vaša emailová adresa bola overená." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Overenie emailovej adresy" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Tento email dostávate, pretože používateľ %(user_display)s zadal vašu " "emailovú adresu na registráciu účtu na %(site_domain)s ." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Váš kód na overenie emailovej adresy je uvedený nižšie. Prosím, zadajte ho " "do otvoreného okna vo vašom prehliadači." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Pre overenie správnosti navštívte %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Potvrďte prosím svoju e-mailovú adresu" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "Emailová adresa %(deleted_email)s bola odstránená z vášho účtu." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Emailová adresa odstránená" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Váš prihlasovací kód je uvedený nižšie. Prosím, zadajte ho do otvoreného " "okna vo vašom prehliadači." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Tento email môžete kľudne ignorovať, ak ste si nevyžiadali túto akciu." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Prihlasovací kód" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Vaše heslo bolo zmenené." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Heslo zmenené" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Tento e-mail ste dostali, pretože niekto požiadal o heslo k vášmu " "používateľskému účtu.\n" "Ak ste to neboli vy, správu môžete pokojne ignorovať. Kliknutím na odkaz " "nižšie obnovíte svoje heslo." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Ak ste náhodou zabudli, vaše používateľské meno je %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-mail pre obnovu hesla" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Vaše heslo bolo obnovené." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Obnoviť heslo" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Vaše heslo bolo nastavené." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Heslo nastavené" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Tento email dostávate, pretože ste sa vy, alebo niekto iný pokúsili " "pristúpiť k účtu s emailovou adresou %(email)s. Avšak, neevidujeme žiaden " "účet s danou adresou v našom systéme." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Ak ste to boli vy, môžete si zaregistrovať nový účet navštívením linku " "nižšie." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Neznámy účet" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "E-mailová adresa" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Súčasná emailová adresa" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Zmeniť na" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Vaša emailová adresa stále čaká na overenie." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Zrušiť zmenu" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Zmeniť na" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Zmeniť e-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Potvrdiť e-mailovú adresu" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Prosím potvrďte, že %(email)s je e-mailová " "adresa pre používateľa %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Nemožno potvrdiť %(email)s pretože už je potvrdený iným používateľom." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Odkaz na potvrdenie e-mailu je neplatný alebo vypršal. Zaslať novú žiadosť o overovací e-mail." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ak ešte nemáte vytvorený účet, tak potom sa prosím najprv " "%(link)szaregistrujte%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Prihlásiť sa prístupovým kľúčom" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Poslať prihlasovací kód" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Odhlásiť" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Ste si istý, že sa chcete odhlásiť?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Primárna e-mailová adresa sa nedá odstrániť (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Overovací e-mail poslaný na %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s potvrdené." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "E-mailová adresa %(email)s úpešne odstránená." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Úspešne ste sa prihlásili ako %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Odhlásili ste sa." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Prihlasovací kód bol odoslaný na %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Zmena hesla prebehla úspešne." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr ")Nastavenie hesla bolo úspešné." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primárna e-mailová adresa bola úspešne zadaná." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Zmeniť heslo" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Zabudnuté heslo?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Zabudli ste heslo? Vložte nižšie svoju e-mailovú adresu a čoskoro vám " "pošleme e-mail na obnovenie hesla." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Obnov moje heslo" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Prosím, kontaktujte nás, ak máte nejaký problém s obnovením svojho hesla." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Poslali sme vám email. Ak ste ho nedostali, skontrolujte si priečinok " "nevyžiadanej pošty. Ak ho v priebehu pár minút neobdržíte, kontaktujte nás." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Zlý token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Odkaz na obnovu heslo je neplatný, pravdepodobne už bol použitý. Nové obnovenie hesla." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Tvoje heslo bolo zmenené." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Nastaviť heslo" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Zadajte svoje heslo:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "Obdržíte email obsahujúci kód, ktorý použijete na prihlásenie." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Vyžiadať kód" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Iné možnosti prihlásenia" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registrácia" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Zaregistrovať" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Už ste sa zaregistrovali? Tak sa %(link)sprihláste%(end_link)s." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "Prihlásiť sa prístupovým kľúčom" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Zaregistrovať" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Iné možnosti prihlásenia" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registrácia uzavretá" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Ospravedlňujeme sa, ale registrácia je momentálne uzavretá." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Poznámka" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Už ste prihlásený ako %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Varovanie:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Momentálne nemáte nastavený žiaden e-mail, kvôli čomu nemôžete dostávať " "upozornenia, obnovovať heslo, atď." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Potvrďte e-mailovú adresu" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Poslali sme Vám overovací e-mail. Kliknutím na uvedený odkaz dokončite " "proces registrácie. Ak ste ho nedostali, skontrolujte si priečinok so " "spamom. V prípade, že do niekoľkých minút nedostanete overovací e-mail, " "kontaktujte nás." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Na prezeranie nasledujúceho obsahu je potrebné overenie vašej e-mailovej " "adresy. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Poslali sme vám overovací e-mail. Kliknite prosím na odkaz v emaili. Ak ste " "email neobdržali, skontrolujte priečinok nevyžiadanej pošty. V prípade, že " "ho do niekoľkých minút nedostanete, kontaktujte nás." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Poznámka: stále môžete zmeniť " "svoju e-mailovú adresu." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Správy:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Pripojenia účtu" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Dvojfaktorová autentifikácia" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Relácie" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Váš účet je chránený dvojfaktorovu autentifikáciou. Prosím zadajte kód z " "autentifikátora:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Boli vygenerované nové záložné kódy pre dvojfaktorovú autentifikáciu." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Nové záložné kódy" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Autentifikačná aplikácia aktivovaná." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Aktivácia autentifikačnej aplikácie" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Autentifikačná aplikácia deaktivovaná." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Deaktivácia autentifikačnej aplikácie" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Bol pridaný nový bezpečnostný kľúč." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Pridaný bezpečnostný kľúč" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Bezpečnostný kľúč bol odstránený." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Odstránený bezpečnostný kľúč" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Autentifikačná aplikácia" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Autentifikácia pomocou aplikácie je aktívna." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Autentifikačná aplikácia je neaktívna." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Deaktivovať" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Aktivovať" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Bezpečnostné kľúče" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Pridali ste si %(count)s bezpečnostný kľúč." msgstr[1] "Pridali ste si %(count)s bezpečnostné kľúče." msgstr[2] "Pridali ste si %(count)s bezpečnostných kľúčov." msgstr[3] "Pridali ste si %(count)s bezpečnostných kľúčov." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Nepridali ste si žiadne bezpečnostné kľúče." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Spravovať" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Pridať" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Kódy obnovy" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "Je k dispozícii %(unused_count)s kódov z celkového počtu %(total_count)s " "kódov obnovy." msgstr[1] "" "Je k dispozícii %(unused_count)s kód z celkového počtu %(total_count)s kódov " "obnovy." msgstr[2] "" "Je k dispozícii %(unused_count)s kódov z celkového počtu %(total_count)s " "kódov obnovy." msgstr[3] "" "Je k dispozícii %(unused_count)s kódu z celkového počtu %(total_count)s " "kódov obnovy." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Nie sú nastavené žiadne kódy obnovy." #: templates/mfa/index.html:96 msgid "View" msgstr "Zobraziť" #: templates/mfa/index.html:102 msgid "Download" msgstr "Stiahnuť" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Generovať" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Boli vygenerované nové kódy obnovy." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Bezpečnostný kľúč pridaný." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Bezpečnostný kľúč odstránený." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Zadajte kód z autentifikátora:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Chystáte sa vygenerovať nové kódy obnovy pre váš účet." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Táto akcia zruší platnosť vašich existujúcich kódov." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Ste si istý?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Nepoužité kódy" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Stiahnuť kódy" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Generovať nové kódy" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Aktivovať autentifikačnú aplikáciu" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Na ochranu vášho účtu dvojfaktorovou autentifikáciou naskenujte QR kód " "nižšie vašou autentifikačnou aplikáciou a následne zadajte nižšie " "vygenerovaný overovací kód." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Heslo prístupového tokenu" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Môžete si uložiť toto heslo a kedykoľvek ho použiť na preinštalovanie vašej " "autentifikačnej aplikaćie." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Deaktivovať autentifikačnú aplikáciu" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "Chystáte sa deaktivovať vašu autentifikačnú aplikáciu. Ste si istý?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Pridať bezpečnostný kľúč" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Odstrániť bezpečnostný kľúč" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Ste si istý, že chcete odstrániť tento bezpečnostný kľúč?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Využitie" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Prístupový kľúč" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Bezpečnostný kľúč" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Tento kľúč neuvádza, či ide o prístupový kľúč." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Neuvedené" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Pridaný %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Naposledy použitý %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Upraviť" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Upraviť bezpečnostný kľúč" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Uložiť" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "Prístupový kľúč" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "vytvorený" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Táto funkcionalita vyžaduje JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Zlyhanie prihlasovania tretej strany" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Pri prihlasovaní sa cez účet tretej strany nastala chyba." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Môžete sa prihlásiť pomocou niektorého z nasledujúcich účtov:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Momentálne nemáte priradený žiaden účet tretej strany." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Pridať účet tretej strany" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "Účet tretej strany %(provider)s bol priradený do vášho účtu." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Priradený účet tretej strany" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "Účet tretej strany %(provider)s bol odstránený z vášho účtu." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Odstránený účet tretej strany" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Prepojiť s %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Chystáte sa prepojiť nový účet tretej strany %(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Prihlásiť sa cez %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "Chystáte sa prihlásiť cez účet tretej strany %(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Pokračovať" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Prihlásenie zrušené" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Rozhodli ste sa zrušiť prihlasovanie sa na našu stránku použitím jedného z " "vašich existujúcich účtov. Ak se chceli vykonať inú operáciu, pokračujte na " "prihlásiť sa." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Účet tretej strany bol priradený." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Účet tretej strany bol odstránený." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Chystáte sa použiť váš %(provider_name)s účet na prihlásenie do\n" "%(site_name)s. Ako posledný krok vyplňte nasledujúci formulár:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Alebo použiť tretiu stranu" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Boli ste odhlásený zo všetkých ostatných relácií." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Začiatok" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP adresa" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Prehliadač" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Naposledy použitá" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Aktuálna relácia" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Odhlásiť sa z ostatných relácií" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Relácie používateľa" #: usersessions/models.py:92 msgid "session key" msgstr "klúč relácie" #~ msgid "Account Connection" #~ msgstr "Pripojené účty" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Heslo musí mať aspoň {0} znakov." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Tento e-mail ste dostali, pretože niekto požiadal o heslo k Vášmu\n" #~ "používateľskému účtu. V našej databáze však nemáme žiadny záznam o " #~ "používateľovi\n" #~ "s e-mailom %(email)s.\n" #~ "\n" #~ "Ak ste nežidali o obnovenie hesla, môžete tento e-mail pokojne " #~ "ignorovať.\n" #~ "\n" #~ "Ak ste to boli Vy, môžete si zaregistrovať účet pomocou odkazu nižšie." #~ msgid "The following email address is associated with your account:" #~ msgstr "Nasledujúce e-mailové adresy sú prepojené s vašim účtom:" #~ msgid "Change Email Address" #~ msgstr "Potvrdiť e-mailovú adresu" #~ msgid "" #~ "To safeguard the security of your account, please enter your password:" #~ msgstr "Kvôli bezpečnosti vášho účtu, zadajte prosím vaše heslo:" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Prosím prihláste sa s jedným\n" #~ "z vašich existujúcich účtov iných služieb. Alebo sa zaregistrujte\n" #~ "na %(site_name)s a prihláste sa nižšie:" #~ msgid "or" #~ msgstr "alebo" #~ msgid "change password" #~ msgstr "zmeniť heslo" #~ msgid "OpenID Sign In" #~ msgstr "Prihlásiť pomocou OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Táto e-mailová adresa je už spojená s iným účtom." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Odoslali sme vám e-mail. Prosím kontaktujte nás ak ste ho nedostali do " #~ "pár minút." django-allauth-65.0.2/allauth/locale/sl/000077500000000000000000000000001467545753200200275ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sl/LC_MESSAGES/000077500000000000000000000000001467545753200216145ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sl/LC_MESSAGES/django.po000066400000000000000000001462341467545753200234300ustar00rootroot00000000000000# Slovenian translations for Django-allauth. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Lev Predan Kowarski , 2020-06-27 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 21:25+0200\n" "Last-Translator: Klemen Štrajhar \n" "Language-Team: Bojan Mihelac , Lev Predan Kowarski, " "Klemen Štrajhar \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " "n%100==4 ? 2 : 3);\n" "X-Translated-Using: django-rosetta 0.7.4\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Račun trenutno ni aktiven." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Primarnega e-poštnega naslova (%(email)s) ni mogoče odstraniti." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "E-poštni naslov že pripada vašemu uporabniškemu računu." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "E-poštni naslov in/ali geslo nista pravilna." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Za ta e-naslov že obstaja registriran uporabnik." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Prosimo vpišite trenutno geslo." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Trenutno geslo" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Napačni žeton" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Žeton za ponastavitev gesla je bil neveljaven." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Vaš uporabniški račun nima preverjenega e-poštnega naslova." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Preveliko število neuspelih prijav. Poskusite znova kasneje." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "E-poštni naslov ne pripada nobenemu uporabniškemu računu." #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Uporabniško ime je neveljavno. Prosimo uporabite drugo uporabniško ime." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Uporabniško ime in/ali geslo nista pravilna." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Ste pozabili geslo?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "žeton skrivnost" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "skrivni ključ" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "" #: account/apps.py:11 msgid "Accounts" msgstr "Računi" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Vnesti je potrebno isto geslo." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Geslo" #: account/forms.py:93 msgid "Remember Me" msgstr "Zapomni si me" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-poštni naslov" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-poštni naslov" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Uporabniško ime" #: account/forms.py:123 msgid "Username or email" msgstr "Uporabniško ime ali e-poštni naslov" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Prijava" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Ste pozabili geslo?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-pooštni naslov (ponovno)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Potrditev e-poštni naslova" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-poštni naslov (neobvezno)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Vnesti je potrebno isti e-poštni naslov." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Geslo (ponovno)" #: account/forms.py:554 msgid "Current Password" msgstr "Trenutno geslo" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Novo geslo" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Novo geslo (ponovno)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "uporabnik" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "E-poštni naslov" #: account/models.py:34 msgid "verified" msgstr "preverjeno" #: account/models.py:35 msgid "primary" msgstr "Primarni" #: account/models.py:41 msgid "email addresses" msgstr "E-poštni naslovi" #: account/models.py:150 msgid "created" msgstr "ustvarjeno" #: account/models.py:151 msgid "sent" msgstr "poslano" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "ključ" #: account/models.py:157 msgid "email confirmation" msgstr "E-poštna potrditev" #: account/models.py:158 msgid "email confirmations" msgstr "E-poštne potrditve" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "skrivni ključ" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Geslo" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Uporabniški račun s tem e-poštnim naslovom že obstaja. Prosimo vpišite se v " "tobstoječi račun, nato %s račune povežite." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Napačni žeton" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Vaš uporabniški račun nima nastavljenega gesla." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Vaš uporabniški račun nima preverjenega e-poštnega naslova." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "Vpišete se lahko s pomčjo vaših obstoječih uoporabniških računov:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Obstoječi račun drugega ponudnika, je povezan z obstoječim računom." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Računi družbenih omrežij." #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "ponudnik" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "ponudnik" #: socialaccount/models.py:56 msgid "name" msgstr "ime" #: socialaccount/models.py:58 msgid "client id" msgstr "id številka" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID aplikacije ali uporoabniški ključ" #: socialaccount/models.py:63 msgid "secret key" msgstr "skrivni ključ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API skrivnost, skrivnost klienta ali uporabniška skrivnost" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Ključ" #: socialaccount/models.py:81 msgid "social application" msgstr "družbena aplikacija" #: socialaccount/models.py:82 msgid "social applications" msgstr "družbene aplikacije" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "zadnja prijava" #: socialaccount/models.py:120 msgid "date joined" msgstr "datum pridružitve" #: socialaccount/models.py:121 msgid "extra data" msgstr "dodatni podatki" #: socialaccount/models.py:125 msgid "social account" msgstr "uporabniški račun družbenih omerižij" #: socialaccount/models.py:126 msgid "social accounts" msgstr "uporabniški računi družbenih omerižij" #: socialaccount/models.py:160 msgid "token" msgstr "žeton" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ali žeton za dostop (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "žeton skrivnost" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ali žeton za osvežitev (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "veljavnost poteče" #: socialaccount/models.py:174 msgid "social application token" msgstr "žeton družebnih omrežij" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "žetoni družbenih omrežij" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Nevelljavni podatki profila" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Prijava" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Neveljaven odgovor ob pridobivanju žetona za zahtevo od \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Neveljaven odgovor ob pridobivanju žetona za dostop od \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Za \"%s\" ni shranjenega žetona za zahtevo." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Za \"%s\" ni shranjenega žetona za dostop." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Ni dostopa do zasebnega vira na \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Neveljaven odgovor ob pridobivanju žetona za zahtevo od \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Neaktiven račun" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Račun ni aktiven." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Potrdite e-poštni naslov" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "E-poštna potrditev" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "žeton skrivnost" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Potrdi" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Prijava" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-poštni naslovi" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "E-poštni naslovi, ki pripadajo vašemu uporabniškemu računu:" #: templates/account/email.html:25 msgid "Verified" msgstr "Preverjeni" #: templates/account/email.html:29 msgid "Unverified" msgstr "Nepreverjeni" #: templates/account/email.html:34 msgid "Primary" msgstr "Primarni" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Spremeni v primarni" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Ponovno pošlji verifikacijo" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Odstrani" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Dodaj e-poštni naslov" #: templates/account/email.html:70 msgid "Add Email" msgstr "Dodaj e-pošto" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Želite odstraniti izbran e-poštni nalsov?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Pozdravljeni iz %(site_name)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Hvala, ker uporabljate %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "E-poštni naslov" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "%(email)s je potrjen." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "E-poštna potrditev" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this e-mail because user %(user_display)s has given your " #| "e-mail address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "To sporočilo ste prejeli, ker je uporabnik %(user_display)s povezal vaš e-" "poštni naslov s svojim uporabniškim računom na %(site_domain)s.\n" "\n" "Za potrditev sledite povezavi: %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Prosimo, potrdite svoj e-poštni naslov." #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Odstrani" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Prijava" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Geslo je spremenjeno." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Geslo (ponovno)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "To sporočilo ste prejeli, ker ste zahtevali ponastavitev gesla za vaš račun." "To sporočilo lahko zavržete, če niste poslali zahtevka za spremembo gesla. " "Za ponastavitev gesla, sledie spodnji povezavi:" #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "V primeru, da ste pozabili, vaše uporabniško ime je: %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "E-poštni naslov za ponastavitev gesla" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Geslo je spremenjeno." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Ponastavitev gesla" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Geslo je spremenjeno." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Ponastavitev gesla" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Accounts" msgid "Unknown Account" msgstr "Računi" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "E-poštni naslovi" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Trenutno geslo" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-poštni naslov" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-poštni naslov" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Potrdite e-poštni naslov" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Prosimo, potrdite, da je %(email)s e-poštni " "naslov uporabnika %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Obstoječi račun drugega ponudnika, je povezan z obstoječim računom." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Povezava za potrditev je neveljavna, ali pa se je iztekla. Prosimo, pošljite nov zahtevek za potrditev.." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Če še nimate uporabniškega računa, ga ustvarite %(link)stukaj%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Odjava" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Ali ste prepričani, da se želite odjaviti?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Primarnega e-poštnega naslova (%(email)s) ni mogoče odstraniti." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Na %(email)s je bilo poslano potrditveno sporočilo." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s je potrjen." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "E-poštni naslov %(email)s je bil odstranjen." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Uspešno ste se prijavili kot %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Odjavili ste se." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Geslo je uspešno zamenjano." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Geslo je uspešno nastavljeno." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primarni e-poštni naslov je nastavljen." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Sprememba gesla" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Ste pozabili geslo?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Vnesite vaš e-potni naslov, na katerega boste prejeli povezavo za " "ponastavitev gesla." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Ponastavi geslo" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "V primeru težav pri ponastavljanju gesla, nas kontaktirajte." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent you an e-mail. If you have not received it please check your " #| "spam folder. Otherwise contact us if you do not receive it in a few " #| "minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Poslali smo vam e-poštno sporočilo s povezavo za \n" "potrditev. Če sporočila ne boste prejeli \n" "v nekaj minutah, nas kontaktirajte." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Napačni žeton" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Povezava za ponastavitev gesla je neveljavna oz. je bila že uporoabljena. " "Prosimo, zahtevajte novo povezavo za " "ponastavitev." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Geslo je spremenjeno." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Nastavi geslo" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Ste pozabili geslo?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Ustvari račun" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Ustvari račun" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Že imate uporabniški račun? %(link)sPrijavite se%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Ustvari račun" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registracija ni mogoča" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Registracija trenutno ni mogoča" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Opomba" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "Prijavljeni ste kot %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Opozorilo:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Trenutno nimate natavljlenega e-poštnega naslova. Priporočamo vam, da dodate " "e-poštni naslov, za prejemanje obvestil, zahtevkv za ponastavitev gesla, ipd." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Potrdite e-poštni naslov." #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. If you do not see the verification e-mail " #| "in your main inbox, check your spam folder. Please contact us if you do " #| "not receive the verification e-mail within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Na vaš e-poštni naslov je bil poslano sporočilo za potrditev. Sledite " "povezavi za zaključek registracije. Če sporočila ne boste prejeli v nekaj " "minutah, nas kontaktirajte." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Za dostop morate potrditi svojo identiteto. \n" "Prosimo, da potrdite navedeni e-poštni naslov." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside that e-mail. If you do not " #| "see the verification e-mail in your main inbox, check your spam folder. " #| "Otherwise\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Poslali smo vam e-poštno sporočilo s povezavo za \n" "potrditev. Če sporočila ne boste prejeli \n" "v nekaj minutah, nas kontaktirajte." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Opomba: e-poštni naslov lahko " "spremenite." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Povezave računov" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "žeton skrivnost" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "žeton skrivnost" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "%(email)s je potrjen." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "žeton skrivnost" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "žeton skrivnost" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "skrivni ključ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "skrivni ključ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Ali ste prepričani, da se želite odjaviti?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "skrivni ključ" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Nepreverjeni" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "skrivni ključ" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Trenutno geslo" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "ustvarjeno" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Prijava z računom drugega ponudnika ni uspela." #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Prišo je do napake ob poskusu prijave z vašim obstoječim računom drugega " "ponudnuka." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "Vpišete se lahko s pomčjo vaših obstoječih uoporabniških računov:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Trenutno nimate povezanega nobenega uporabniškega računa drugega ponudnika." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Dodaj obstoječi račun drugega ponudnika" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Dodaj obstoječi račun drugega ponudnika" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Dodaj obstoječi račun drugega ponudnika" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Prijava je bila prekinjena" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Odločili ste se za prekinitev prijave v našo storitev s pomočjo obstoječega " "računa. Če gre za napako, se lahko prijavite tukaj." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Obstoječi račun je povezan." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Obstoječi uporabniški račun je razvezan." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Uporabili boste svoj obstoječi %(provider_name)s račun, za vpis v\n" "%(site_name)s. Prosimo izpolnite spodnji obrazec:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "E-poštni naslovi" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Trenutno geslo" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Povezave računov" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Geslo mora vsebovati najmanj {0} znakov. " #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Pozdravljeni od %(site_name)s!\n" #~ "To sporočilo ste prejeli, ker ste zahtevali ponastavitev gesla na " #~ "%(site_name)s!\n" #~ "To sporočilo lahko zavržete, če niste poslali zahtevka za spremembo " #~ "gesla. Za ponastavitev gelsa, sledie spodnji pvezavi:" #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "E-poštni naslovi, ki pripadajo vašemu uporabniškemu računu:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Potrdite e-poštni naslov" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Prosimo, vpišite se z enim od vaših\n" #~ "obstoječih računov, ali pa %(link)sustvarite nov račun\n" #~ "na %(site_name)s in se vpišite spodaj:" #~ msgid "or" #~ msgstr "ali" #~ msgid "change password" #~ msgstr "Sprememba gesla" #~ msgid "OpenID Sign In" #~ msgstr "Prijava z OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "E-poštni naslov že pripada drugemu uporabniškemu računu." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Povezava za ponastavitev gesla je bila poslana. Če je ne boste prejeli v " #~ "nekaj minutah, nas kontaktirajte." django-allauth-65.0.2/allauth/locale/sr/000077500000000000000000000000001467545753200200355ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sr/LC_MESSAGES/000077500000000000000000000000001467545753200216225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sr/LC_MESSAGES/django.po000066400000000000000000001560131467545753200234320ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Nikola Vulovic , 2018. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-06-30 16:28+0200\n" "Last-Translator: dex girl \n" "Language-Team: Serbian \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Weblate 5.6-rc\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Овај налог је тренутно неактиван." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Не можете да уклоните примарну адресу е-поште ." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Ова адреса е-поште је већ повезана са овим налогом." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Адреса е-поште и/или лозинка коју сте навели нису тачни." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Корисник је већ регистрован на овој адреси е-поште." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Молимо унесите тренутну лозинку." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Nepravilan kod." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Nepravilna lozinka." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Loš ili istekao ključ." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Токен ресетовања лозинке је неважећи." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Ne možeš dodati više od %d imejl adresa." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Превише неуспелих покушаја пријављивања. Покушајте поново касније." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Адреса е-поште није додељена било ком корисничком налогу" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Ваша примарна адреса е-поште мора бити потврђена." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Корисничко име се не може користити. Молимо користите друго корисничко име." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Корисничко име и/или лозинка коју сте навели нису тачни." #: account/adapter.py:741 msgid "Use your password" msgstr "Koristi vašu lozinku" #: account/adapter.py:750 #, fuzzy #| msgid "Use your authenticator app" msgid "Use authenticator app or code" msgstr "Koristi tvoju autentikatorsku aplikaciju" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "тајни кључ" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Izaberi izabranu e mail adresu kao verifikovanu" #: account/apps.py:11 msgid "Accounts" msgstr "Рачуни" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Морате унијети исту лозинку сваки пут" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Лозинка" #: account/forms.py:93 msgid "Remember Me" msgstr "Сети ме се" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Адреса е-поште" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Е-пошта" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Корисничко име" #: account/forms.py:123 msgid "Username or email" msgstr "Корисничко име или е-пошта" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Пријавите се" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Заборавили сте лозинку?" #: account/forms.py:299 msgid "Email (again)" msgstr "Е-пошта (опет)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Потврда адресе е-поште" #: account/forms.py:311 msgid "Email (optional)" msgstr "Е-пошта (опционо)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Морате унијети исту адресу е-поште сваки пут." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Лозинка (поново)" #: account/forms.py:554 msgid "Current Password" msgstr "Тренутна лозинка" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Нова лозинка" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Нова лозинка (поново)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "kod" #: account/models.py:26 msgid "user" msgstr "корисник" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "адреса е-поште" #: account/models.py:34 msgid "verified" msgstr "проверено" #: account/models.py:35 msgid "primary" msgstr "примарна" #: account/models.py:41 msgid "email addresses" msgstr "адресе е-поште" #: account/models.py:150 msgid "created" msgstr "створено" #: account/models.py:151 msgid "sent" msgstr "послат" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "кључ" #: account/models.py:157 msgid "email confirmation" msgstr "потврда е-поште" #: account/models.py:158 msgid "email confirmations" msgstr "потврде е-поште" #: headless/apps.py:7 msgid "Headless" msgstr "bez glave" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Ne možeš dodati e mail adresu na nalog sa dvo faktorskom autentifikacijom." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Ne možeš deaktivirati dvofaktorsku autentifikaciju." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Ne možeš generisati povratne kodove bez dozvoljene dvofaktorske " "autentifikacije." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Ne možeš aktivirati dvofaktorsku autentifikaciju dok nisi verifikovao tvoju " "e mail adresu." #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "тајни кључ" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Povratni kodovi" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP autentikator" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Autentikatorski kod" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Лозинка" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Рачун постоји већ са овом адресом е поште. Пријавите се на топрви налог, " "затим повежите свој %s налог." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Лош токен" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Ваш налог нема подешену лозинку." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Ваш налог нема потврђену е-маил адресу." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Ne možeš odjaviti tvoj preostao trodelni nalog." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Друштвени рачун је већ повезан са другим налогом." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Друштвени рачуни" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "провидер" #: socialaccount/models.py:52 msgid "provider ID" msgstr "провидер ID" #: socialaccount/models.py:56 msgid "name" msgstr "име" #: socialaccount/models.py:58 msgid "client id" msgstr "ИД клијента" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ИД апликације или потрошачки кључ" #: socialaccount/models.py:63 msgid "secret key" msgstr "тајни кључ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Тајна АПИ-ја, тајна клијента или тајна потрошача" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Кључ" #: socialaccount/models.py:81 msgid "social application" msgstr "друштвена апликација" #: socialaccount/models.py:82 msgid "social applications" msgstr "друштвена апликације" #: socialaccount/models.py:117 msgid "uid" msgstr "уид" #: socialaccount/models.py:119 msgid "last login" msgstr "Последње пријављивање" #: socialaccount/models.py:120 msgid "date joined" msgstr "Датум придружио" #: socialaccount/models.py:121 msgid "extra data" msgstr "додатни подаци" #: socialaccount/models.py:125 msgid "social account" msgstr "друштвени рачун" #: socialaccount/models.py:126 msgid "social accounts" msgstr "друштвени рачуни" #: socialaccount/models.py:160 msgid "token" msgstr "токен" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) или токен приступа (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "токен тајна" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) или освежени токен (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "истиче у" #: socialaccount/models.py:174 msgid "social application token" msgstr "Токен друштвених апликација" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "токени друштвених апликација" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Невељавни подаци о профилу" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Пријавите се" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "odustati" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Неважећи одговор при добијању токена за захтев од %s. Odgovr je: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Неважећи одговор при добијању токена за приступ од \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "нема сачуваних токена за захтев од \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "нема сачуваних токена за приступ од \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Нема приступа приватним ресурсима у \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Неважећи одговор при добијању токена за захтев од \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Рачун неактиван" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Овај налог је неактиван." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Potvrda pristupa" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Alternativne opcije" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "потврда е-поште" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "токен тајна" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Poslali smo kod na %(email_link)s. Kod kratko važi, pa ga uskoro ukucajte." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Потврди" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Пријавите се" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Upiši kod za prijavu" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Адресе е-поште" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "С вашим налогом су повезане следеће адресе е-пошти:" #: templates/account/email.html:25 msgid "Verified" msgstr "Потврђено" #: templates/account/email.html:29 msgid "Unverified" msgstr "Непотврђени" #: templates/account/email.html:34 msgid "Primary" msgstr "Примарни" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Постави за Примарни" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Поновно пошаљи верификацију" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Уклони" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Додај адресу е-поште" #: templates/account/email.html:70 msgid "Add Email" msgstr "Додај е-пошту" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Да ли стварно желите да уклоните изабрану адресу е-поште?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Dobijate ovaj e mail zato što vi ili neko drugi pokušava da se registruje " "nalog koristeći e mail adresu. \n" "\n" "%(email)s\n" "\n" "Svakako, nalog koji koristi tu e mail adresu već postoji. U slučaju da ste " "zaboravili na ovo, molim vas koristite šifra zaboravljena proceduru da " "vratite vaš nalog. \n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Nalog već postoji" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Hvala od %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Хвала вам што користите %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Dobijate ovaj mejl zato što su sledeće promene izvršene na vaš nalog:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Ako ne prepoznajete ove promene onda molim vas preduzmite mere zaštite " "odmah. Promene na vašem nalogu dolaze od:\n" "\n" "Ip adrese: %(ip)s\n" "Browser: %(user_agent)s\n" "Datum: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Vaš e mail se promenio od %(from_email)s na %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E mail promenjen" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Vaš e mail je potvrđen." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "потврда е-поште" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Dobijate ovaj imejl zato što je korisnik %(user_display)s dao vašu email " "adresu na registraciju naloga na %(site_domain)s.\n" "\n" "Da potvrdite da je ovo tačno, idite na %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Vaš registracioni kod je prikazan ispod. Molim vas unesite ga u vašem " "otvorenom browser prozoru." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Молим вас потврдите вашу адресу е-поште" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "Email adresa %(deleted_email)s je obrisana sa vašeg naloga." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Email uklonjen" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Vaš registracioni kod je prikazan ispod. Molim vas unesite ga u vašem " "otvorenom browser prozoru." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Ovaj mejl može biti bezbedno ignorisan ako ne uradite ovu radnju." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "registracioni kod" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Vaša lozinka je promenjena." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Lozinka promenjena" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Primate ovaj email zato što te vi ili neko drugi tražili resetovanje šifre " "za vaš korisnički nalog.\n" "Može biti bezbedno ignorisan aqko niste tražili resetovanje šifre. Kliknite " "na link ispod da resetujete vašu šifru." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "У случају да сте заборавили, ваше корисничко име је %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Поништавање лозинке е-поштом" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Vaša lozinka je resetovana." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Поништаванје лозинке" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Ваша лозинка је сада промењена." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Stavljanje lozinke" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Primate ovaj email zato što ste vi ili neko drugi pokušali da pristupite " "nalogu sa imejlom %(email)s . Svakako, nemamo podatak o nalogu u našoj bazi." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "Ako ste vi, možete se registrovati za nalog koristeći link ispod." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Nepoznati nalog" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "email adresa" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Trenutni email" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Promena u" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Vaša email adresa još čeka potvrdu." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Otkažite promenu" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Promenite u" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Promenite email" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Потврда адресе е-поште" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Molim vas potvrdite da je email adresa za " "korisnika %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Neuspela potvrda %(email)s zato što je već potvrđen drugim nalogom." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Ovaj email link za potvrdu je istekao ili je nevažeći. Molim vas tražite novu potvrdu e maila." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ако још нисте створили рачун, онда се прво %(link)sрегиструјте%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Pošaljite mi registracioni kod" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Одјава" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Јесте ли сигурни да желите да се одјавите?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Не можете да уклоните примарну адресу е-поште (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Потврдна порука је послата на адресу е-поште %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Потврдили сте %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Уклоњена адреса e-поште %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Успешно сте се пријавили као %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Одјавили сте се." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Registracioni kod je poslat %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Лозинка је успешно промењена." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Успешно сте поставили лозинку." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Примарна адреса е-поште постављена." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Промени лозинку" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Заборавили сте лозинку?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Zaboravili ste vašu lozinku? Unesi vašu email adresu ispod, i poslaćemo vam " "email koji vam dozvoljava da resetujete." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Поништи моју лозинку" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Молимо вас да нас контактирате ако имате проблема са поништавањем ваше " "лозинке." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Poslali smo vam mejl. Ako ga niste primili polim vas proverite vaš spam " "folder. U suprotnom nas kontaktirajte ako ga ne primite za par minuta." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Лош токен" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Веза за поништавање лозинке је неважећа, вероватно зато што је већ " "билаискоришћена. Молимо Вас да затражите ново поништаванје лозинке." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Ваша лозинка је сада промењена." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Постави лозинку" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Unesi vašu šifru:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Dobićete email koji sadrži specijalni kod za šifrovano besplatno " "registrovanje." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Zahteva kod" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Druge opcije prijave" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Регистрација" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Региструјте се" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Већ имате налог? Онда Вас молимо да %(link)sсе пројавите%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Региструјте се" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Druge opcije prijave" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Регистрација затворена" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Жао нам је, али регистрација је тренутно затворена." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Напомена" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Veš ste prijavljeni kao %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Упозорење:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Trenutno nemate nijednu postavljenu e mail adresu. Treba stvarno da dodate " "email adresu kako biste primali obaveštenja, resetovali vašu šifru,itd." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Потврдите Вашу адресу е-поште" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Poslali smo vam email za vašu potvrdu. Pratite link da završite proces " "registrovanja. Ako ne vidite verifikacioni emaill u vašem glavnom imboksu " "proverite vaš spam folder. Molim vas kontaktirajte nas ukoliko ne primite " "verifikacioni email za par minuta." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Овај део сајта захтева од Вас да потврдите да\n" "сте Ви заиста за особа која тврдите да сте. У ову сврху захтевамо да\n" "потврдите власништво над вашом адресом е-поште." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Послали смо вам поруку е-поштом за\n" "верификацију. Кликните на везу унутар ове е-поруке.\n" "Контактирајте нас ако не примите е-поруку у року од неколико минута." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Напомена: и даље можете да " "промените адресу Вашее-поште." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Повезани рачуни" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "токен тајна" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "токен тајна" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your email has been confirmed." msgid "A security key has been removed." msgstr "Vaš e mail je potvrđen." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "токен тајна" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "токен тајна" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "тајни кључ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "тајни кључ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Јесте ли сигурни да желите да се одјавите?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "тајни кључ" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Непотврђени" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "тајни кључ" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Тренутна лозинка" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "створено" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Друштвене мрежа пријава неуспешна" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Дошло је до грешке приликом покушаја пријављивања преко налога ваше " "друштвене мреже." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Можете се пријавити на свој рачун помоћу било које од следећих рачуна " "трећихстрана:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Тренутно немате ниједан рачун друштевених мрежа повезане са овим рачуном." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Додајте рачун треће стране" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Додајте рачун треће стране" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Додајте рачун треће стране" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Пријава је отказана" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Одлучили сте да откажете пријављивање на нашу веб страницу помоћу једног од " "ваших постојећихрачуна. Ако је ово грешка, молимо вас да пређете на и прјавите се." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Друштвени рачун је повезан." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Друштвени рачун више није повезан." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Управо користите свој рачун код %(provider_name)s да бисте се пријавили на\n" "%(site_name)s. Као последњи корак, молимо попуните следећи образац:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Адресе е-поште" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Тренутна лозинка" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Повезани рачуни" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Лозинка мора бити најмање {0} знакова." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Здраво од %(site_name)s!\n" #~ "\n" #~ "Примате ову е-маил поруку јер сте ви или неко други тражилилозинку за ваш " #~ "кориснички налог.\n" #~ "Ова порука се може игнорисати ако нисте затражили ресет лозинке. Кликните " #~ "на линк испод да бисте поништили своју лозинку." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "С вашим налогом су повезане следеће адресе е-пошти:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Потврда адресе е-поште" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Молимо Вас да се пријавите са једним од\n" #~ "постојећих рачуна трећих страна. Или, се региструјте\n" #~ "за рачун код %(site_name)s и пријавите се доле:" #~ msgid "or" #~ msgstr "или" #~ msgid "change password" #~ msgstr "промени лозинку" #~ msgid "OpenID Sign In" #~ msgstr "ОпенИД Пријава" #~ msgid "This email address is already associated with another account." #~ msgstr "Ова адреса е-поште је већ повезана са другим налогом." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Послали смо вам е-пошту. Молимо Вас да нас контактирате ако га не " #~ "примитеза неколико минута." django-allauth-65.0.2/allauth/locale/sr_Latn/000077500000000000000000000000001467545753200210135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sr_Latn/LC_MESSAGES/000077500000000000000000000000001467545753200226005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sr_Latn/LC_MESSAGES/django.po000066400000000000000000001467051467545753200244170ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Nikola Vulovic , 2018. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:07+0200\n" "Last-Translator: Nikola Vulovic \n" "Language-Team: NONE\n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Ovaj nalog je trenutno neaktivan." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Ne možete da uklonite primarnu adresu e-pošte (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Ova adresa e-pošte je već povezana sa ovim nalogom." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Adresa e-pošte i/ili lozinka koju ste naveli nisu tačni." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Korisnik je već registrovan na ovoj adresi e-pošte." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Molimo unesite trenutnu lozinku." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Trenutna lozinka" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Loš token" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Token resetovanja lozinke je nevažeći." #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Vaš nalog nema potvrđenu e-mail adresu." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Previše neuspelih pokušaja prijavljivanja. Pokušajte ponovo kasnije." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Adresa e-pošte nije dodeljena bilo kom korisničkom nalogu" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Vaša primarna adresa e-pošte mora biti potvrđena." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Korisničko ime se ne može koristiti. Molimo koristite drugo korisničko ime." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Korisničko ime i/ili lozinka koju ste naveli nisu tačni." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Zaboravili ste lozinku?" #: account/adapter.py:750 #, fuzzy #| msgid "token secret" msgid "Use authenticator app or code" msgstr "token tajna" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "tajni ključ" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Vaša primarna adresa e-pošte mora biti potvrđena." #: account/apps.py:11 msgid "Accounts" msgstr "Računi" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Morate unijeti istu lozinku svaki put" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Lozinka" #: account/forms.py:93 msgid "Remember Me" msgstr "Seti me se" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Adresa e-pošte" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-pošta" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Korisničko ime" #: account/forms.py:123 msgid "Username or email" msgstr "Korisničko ime ili e-pošta" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Prijavite se" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Zaboravili ste lozinku?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-pošta (opet)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Potvrda adrese e-pošte" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-pošta (opciono)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Morate unijeti istu adresu e-pošte svaki put." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Lozinka (ponovo)" #: account/forms.py:554 msgid "Current Password" msgstr "Trenutna lozinka" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nova lozinka" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nova lozinka (ponovo)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "korisnik" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "adresa e-pošte" #: account/models.py:34 msgid "verified" msgstr "provereno" #: account/models.py:35 msgid "primary" msgstr "primarna" #: account/models.py:41 msgid "email addresses" msgstr "adrese e-pošte" #: account/models.py:150 msgid "created" msgstr "stvoreno" #: account/models.py:151 msgid "sent" msgstr "poslat" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "ključ" #: account/models.py:157 msgid "email confirmation" msgstr "potvrda e-pošte" #: account/models.py:158 msgid "email confirmations" msgstr "potvrde e-pošte" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 #, fuzzy #| msgid "secret key" msgid "Master key" msgstr "tajni ključ" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Lozinka" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Račun postoji već sa ovom adresom e-pošte. Prijavite se na toprvi nalog, " "zatim povežite svoj %s nalog." #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Loš token" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Vaš nalog nema podešenu lozinku." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Vaš nalog nema potvrđenu e-mail adresu." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Možete se prijaviti na svoj račun pomoću bilo koje od sledećih računa " "trećihstrana:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Društveni račun je već povezan sa drugim nalogom." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Društveni računi" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "provider" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "provider" #: socialaccount/models.py:56 msgid "name" msgstr "ime" #: socialaccount/models.py:58 msgid "client id" msgstr "ID klijenta" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "ID aplikacije ili potrošački ključ" #: socialaccount/models.py:63 msgid "secret key" msgstr "tajni ključ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "Tajna API-ja, tajna klijenta ili tajna potrošača" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Ključ" #: socialaccount/models.py:81 msgid "social application" msgstr "društvena aplikacija" #: socialaccount/models.py:82 msgid "social applications" msgstr "društvena aplikacije" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "Poslednje prijavljivanje" #: socialaccount/models.py:120 msgid "date joined" msgstr "Datum pridružio" #: socialaccount/models.py:121 msgid "extra data" msgstr "dodatni podaci" #: socialaccount/models.py:125 msgid "social account" msgstr "društveni račun" #: socialaccount/models.py:126 msgid "social accounts" msgstr "društveni računi" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) ili token pristupa (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token tajna" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) ili osveženi token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "ističe u" #: socialaccount/models.py:174 msgid "social application token" msgstr "Token društvenih aplikacija" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "tokeni društvenih aplikacija" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Neveljavni podaci o profilu" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Prijavite se" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Nevažeći odgovor pri dobijanju tokena za zahtev od \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Nevažeći odgovor pri dobijanju tokena za pristup od \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "nema sačuvanih tokena za zahtev od \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "nema sačuvanih tokena za pristup od \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Nema pristupa privatnim resursima u \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Nevažeći odgovor pri dobijanju tokena za zahtev od \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Račun neaktivan" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Ovaj nalog je neaktivan." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Potvrda adrese e-pošte" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "potvrda e-pošte" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "token secret" msgid "Enter Email Verification Code" msgstr "token tajna" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Potvrdi" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Prijavite se" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Adrese e-pošte" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "S vašim nalogom su povezane sledeće adrese e-pošti:" #: templates/account/email.html:25 msgid "Verified" msgstr "Potvrđeno" #: templates/account/email.html:29 msgid "Unverified" msgstr "Nepotvrđeni" #: templates/account/email.html:34 msgid "Primary" msgstr "Primarni" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Postavi za Primarni" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Ponovno pošalji verifikaciju" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Ukloni" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Dodaj adresu e-pošte" #: templates/account/email.html:70 msgid "Add Email" msgstr "Dodaj e-poštu" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Da li stvarno želite da uklonite izabranu adresu e-pošte?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, fuzzy, python-format #| msgid "" #| "Thank you from %(site_name)s!\n" #| "%(site_domain)s" msgid "Hello from %(site_name)s!" msgstr "" "Hvala od %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Hvala vam što koristite %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Adresa e-pošte" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "Your email has been confirmed." msgstr "Potvrdili ste %(email)s." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "potvrda e-pošte" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because user %(user_display)s has given " #| "yours as an e-mail address to connect their account.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Zdravo iz %(site_name)s!\n" "\n" "Primate ovaj e-mail pošto je korisnik %(user_display)s dao vašutvojadresu za " "povezivanje sa njihovim nalogaom.\n" "\n" "Da biste potvrdili ovo, idite na %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Molim vas potvrdite vašu adresu e-pošte" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Ukloni" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Prijavite se" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Vaša lozinka je sada promenjena." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Lozinka (ponovo)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "Hello from %(site_name)s!\n" #| "\n" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Zdravo od %(site_name)s!\n" "\n" "Primate ovu e-mail poruku jer ste vi ili neko drugi tražililozinku za vaš " "korisnički nalog.\n" "Ova poruka se može ignorisati ako niste zatražili reset lozinke. Kliknite na " "link ispod da biste poništili svoju lozinku." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "U slučaju da ste zaboravili, vaše korisničko ime je %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Poništavanje lozinke e-poštom" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been reset." msgstr "Vaša lozinka je sada promenjena." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Poništavanje lozinke" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been set." msgstr "Vaša lozinka je sada promenjena." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Poništavanje lozinke" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Račun" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Adrese e-pošte" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Trenutna lozinka" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Vaša primarna adresa e-pošte mora biti potvrđena." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-pošta" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-pošta" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Potvrda adrese e-pošte" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Molimo potvrdite da je %(email)s je adresa " "e-pošte za korisnika %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Društveni račun je već povezan sa drugim nalogom." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Ovaj link za potvrdu e-pošte je istekao ili je nevažeći. Molimo vas da zatražite novi zahtev za potvrdu e-pošte ." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Ako još niste stvorili račun, onda se prvo %(link)sregistrujte%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Odjava" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Jeste li sigurni da želite da se odjavite?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Ne možete da uklonite primarnu adresu e-pošte (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Potvrdna poruka je poslata na adresu e-pošte %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Potvrdili ste %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Uklonjena adresa e-pošte %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Uspešno ste se prijavili kao %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Odjavili ste se." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Lozinka je uspešno promenjena." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Uspešno ste postavili lozinku." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primarna adresa e-pošte postavljena." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Promeni lozinku" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Zaboravili ste lozinku?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Zaboravili ste lozinku? Unesite svoju adresu e-pošte ispod, i poslat ćemo " "vame-poštu koji vam omogućava da je poništite." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Poništi moju lozinku" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Molimo vas da nas kontaktirate ako imate problema sa poništavanjem vaše " "lozinke." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Poslali smo vam poruku e-poštom za\n" "verifikaciju. Kliknite na vezu unutar ove e-poruke.\n" "Kontaktirajte nas ako ne primite e-poruku u roku od nekoliko minuta." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Loš token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Veza za poništavanje lozinke je nevažeća, verovatno zato što je već " "bilaiskorišćena. Molimo Vas da zatražite novo poništavanje lozinke." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Vaša lozinka je sada promenjena." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Postavi lozinku" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Zaboravili ste lozinku?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Registracija" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Registrujte se" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Već imate nalog? Onda Vas molimo da %(link)sse projavite%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Registrujte se" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Registracija zatvorena" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Žao nam je, ali registracija je trenutno zatvorena." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Napomena" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "Vi ste već prijavljeni kao %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Upozorenje:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Trenutno nemate nikakvu adresu e-pošte. Trebali biste stvarno dodatiadresu e-" "pošte kako biste mogli primati obaveštenja, resetovati lozinku itd." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Potvrdite Vašu adresu e-pošte" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Poslali smo vam poruku e-poštom za verifikaciju. Pratite datu vezu koji ste " "mogli da završite proces registracije. Molimo vas da nas kontaktirate ako ga " "ne primiteza nekoliko minuta." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Ovaj deo sajta zahteva od Vas da potvrdite da\n" "ste Vi zaista za osoba koja tvrdite da ste. U ovu svrhu zahtevamo da\n" "potvrdite vlasništvo nad vašom adresom e-pošte." #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Poslali smo vam poruku e-poštom za\n" "verifikaciju. Kliknite na vezu unutar ove e-poruke.\n" "Kontaktirajte nas ako ne primite e-poruku u roku od nekoliko minuta." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Napomena: i dalje možete da " "promenite adresu Vašee-pošte." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Povezani računi" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Activated" msgstr "token tajna" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 #, fuzzy #| msgid "token secret" msgid "Authenticator App Deactivated" msgstr "token tajna" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "You have confirmed %(email)s." msgid "A security key has been removed." msgstr "Potvrdili ste %(email)s." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" msgstr[2] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 #, fuzzy #| msgid "token secret" msgid "Enter an authenticator code:" msgstr "token tajna" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 #, fuzzy #| msgid "token secret" msgid "Authenticator secret" msgstr "token tajna" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "tajni ključ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "tajni ključ" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Jeste li sigurni da želite da se odjavite?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "tajni ključ" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Nepotvrđeni" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "tajni ključ" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Trenutna lozinka" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "stvoreno" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Društvene mreža prijava neuspešna" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Došlo je do greške prilikom pokušaja prijavljivanja preko naloga vaše " "društvene mreže." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Možete se prijaviti na svoj račun pomoću bilo koje od sledećih računa " "trećihstrana:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "" "Trenutno nemate nijedan račun društevenih mreža povezane sa ovim računom." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Dodajte račun treće strane" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Dodajte račun treće strane" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Dodajte račun treće strane" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Prijava je otkazana" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Odlučili ste da otkažete prijavljivanje na našu veb stranicu pomoću jednog " "od vaših postojećihračuna. Ako je ovo greška, molimo vas da pređete na i prjavite se." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Društveni račun je povezan." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Društveni račun više nije povezan." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Upravo koristite svoj račun kod %(provider_name)s da biste se prijavili na\n" "%(site_name)s. Kao poslednji korak, molimo popunite sledeći obrazac:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Adrese e-pošte" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Trenutna lozinka" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Povezani računi" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Lozinka mora biti najmanje {0} znakova." #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Zdravo od %(site_name)s!\n" #~ "\n" #~ "Primate ovu e-mail poruku jer ste vi ili neko drugi tražililozinku za vaš " #~ "korisnički nalog.\n" #~ "Ova poruka se može ignorisati ako niste zatražili reset lozinke. Kliknite " #~ "na link ispod da biste poništili svoju lozinku." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "S vašim nalogom su povezane sledeće adrese e-pošti:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Potvrda adrese e-pošte" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Molimo Vas da se prijavite sa jednim od\n" #~ "postojećih računa trećih strana. Ili, se registrujte\n" #~ "za račun kod %(site_name)s i prijavite se dole:" #~ msgid "or" #~ msgstr "ili" #~ msgid "change password" #~ msgstr "promeni lozinku" #~ msgid "OpenID Sign In" #~ msgstr "OpenID Prijava" #~ msgid "This email address is already associated with another account." #~ msgstr "Ova adresa e-pošte je već povezana sa drugim nalogom." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Poslali smo vam e-poštu. Molimo Vas da nas kontaktirate ako ga ne " #~ "primiteza nekoliko minuta." django-allauth-65.0.2/allauth/locale/sv/000077500000000000000000000000001467545753200200415ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sv/LC_MESSAGES/000077500000000000000000000000001467545753200216265ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/sv/LC_MESSAGES/django.po000066400000000000000000001447341467545753200234450ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:08+0200\n" "Last-Translator: Jannis Š\n" "Language-Team: Swedish (http://www.transifex.com/projects/p/django-allauth/" "language/sv/)\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Detta konto är inaktivt." #: account/adapter.py:53 #, fuzzy #| msgid "You cannot remove your primary email address (%(email)s)." msgid "You cannot remove your primary email address." msgstr "Du kan inte ta bort din primära epost-adress (%(email)s)." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Denna epost-adress är redan knuten till detta konto" #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Epost-adressen och/eller lösenordet är felaktigt." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "En användare är redan registrerad med den här epost-adressen" #: account/adapter.py:62 msgid "Please type your current password." msgstr "Skriv in ditt nuvarande lösenord." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "" #: account/adapter.py:64 #, fuzzy #| msgid "Current Password" msgid "Incorrect password." msgstr "Nuvarande lösenord" #: account/adapter.py:65 #, fuzzy #| msgid "Bad Token" msgid "Invalid or expired key." msgstr "Felaktig nyckel" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "" #: account/adapter.py:67 #, fuzzy, python-format #| msgid "Your account has no verified email address." msgid "You cannot add more than %d email addresses." msgstr "Ditt konto har ingen verifierad epost-adress." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Epost-adressen är inte knuten till något konto" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Din primära epost-adress måste verifieras." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Användarnamnet kan ej användas. Välj ett annat användarnamn." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Användarnamnet och/eller lösenordet är felaktigt." #: account/adapter.py:741 #, fuzzy #| msgid "Forgot Password?" msgid "Use your password" msgstr "Glömt lösenordet?" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "" #: account/admin.py:23 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Mark selected email addresses as verified" msgstr "Din primära epost-adress måste verifieras." #: account/apps.py:11 #, fuzzy msgid "Accounts" msgstr "Konto" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Du måste ange samma lösenord" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Lösenord" #: account/forms.py:93 msgid "Remember Me" msgstr "Kom ihåg mig" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Epost-adress" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Epost" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Användarnamn" #: account/forms.py:123 msgid "Username or email" msgstr "Användarnamn eller epost-adress" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Logga in" #: account/forms.py:137 #, fuzzy #| msgid "Forgot Password?" msgid "Forgot your password?" msgstr "Glömt lösenordet?" #: account/forms.py:299 #, fuzzy #| msgid "Email (optional)" msgid "Email (again)" msgstr "Epost (valfritt)" #: account/forms.py:303 #, fuzzy #| msgid "email confirmation" msgid "Email address confirmation" msgstr "epost-bekräftelse" #: account/forms.py:311 msgid "Email (optional)" msgstr "Epost (valfritt)" #: account/forms.py:370 #, fuzzy #| msgid "You must type the same password each time." msgid "You must type the same email each time." msgstr "Du måste ange samma lösenord" #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Lösenord (igen)" #: account/forms.py:554 msgid "Current Password" msgstr "Nuvarande lösenord" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Nytt lösenord" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Nytt lösenord (igen)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "" #: account/models.py:26 msgid "user" msgstr "" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "epost-adress" #: account/models.py:34 #, fuzzy msgid "verified" msgstr "Ej verifierad" #: account/models.py:35 #, fuzzy msgid "primary" msgstr "Primär" #: account/models.py:41 msgid "email addresses" msgstr "epost-adresser" #: account/models.py:150 msgid "created" msgstr "" #: account/models.py:151 msgid "sent" msgstr "" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "" #: account/models.py:157 msgid "email confirmation" msgstr "epost-bekräftelse" #: account/models.py:158 msgid "email confirmations" msgstr "epost-bekräftelser" #: headless/apps.py:7 msgid "Headless" msgstr "" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" #: mfa/adapter.py:141 msgid "Master key" msgstr "" #: mfa/adapter.py:143 msgid "Backup key" msgstr "" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "" #: mfa/models.py:24 msgid "Recovery codes" msgstr "" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "" #: mfa/models.py:26 msgid "WebAuthn" msgstr "" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "" #: mfa/webauthn/forms.py:56 #, fuzzy #| msgid "Password" msgid "Passwordless" msgstr "Lösenord" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" #: socialaccount/adapter.py:40 #, fuzzy #| msgid "Bad Token" msgid "Invalid token." msgstr "Felaktig nyckel" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Ditt konto har inget lösenord." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Ditt konto har ingen verifierad epost-adress." #: socialaccount/adapter.py:44 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Du kan logga in på ditt konto via något av följande tredjeparts-konton:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "Tredjeparts-kontot är redan knutet till ett annat konto." #: socialaccount/apps.py:9 #, fuzzy msgid "Social Accounts" msgstr "Konto" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "" #: socialaccount/models.py:52 msgid "provider ID" msgstr "" #: socialaccount/models.py:56 #, fuzzy msgid "name" msgstr "Användarnamn" #: socialaccount/models.py:58 msgid "client id" msgstr "" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "" #: socialaccount/models.py:63 msgid "secret key" msgstr "" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "" #: socialaccount/models.py:81 msgid "social application" msgstr "" #: socialaccount/models.py:82 msgid "social applications" msgstr "" #: socialaccount/models.py:117 msgid "uid" msgstr "" #: socialaccount/models.py:119 msgid "last login" msgstr "" #: socialaccount/models.py:120 msgid "date joined" msgstr "" #: socialaccount/models.py:121 msgid "extra data" msgstr "" #: socialaccount/models.py:125 msgid "social account" msgstr "" #: socialaccount/models.py:126 msgid "social accounts" msgstr "" #: socialaccount/models.py:160 msgid "token" msgstr "" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "" #: socialaccount/models.py:174 msgid "social application token" msgstr "" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "Logga in" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Felaktigt svar vid hämtning av fråge-nyckel från \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Felaktigt svar vid hämtning av access-nyckel från \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Ingen fråge-nyckel sparad för \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Ingen access-nyckel sparad för \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Ingen access till privata resurser hos \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Felaktigt svar vid hämtning av fråge-nyckel från \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Kontot inaktivt" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Detta konto är inaktivt." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "Verifiera epost-adress" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "epost-bekräftelse" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Verifiera" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Logga in" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Epost-adresser" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Följande epost-adresser är knutna till ditt konto:" #: templates/account/email.html:25 msgid "Verified" msgstr "Verifierad" #: templates/account/email.html:29 msgid "Unverified" msgstr "Ej verifierad" #: templates/account/email.html:34 msgid "Primary" msgstr "Primär" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Gör primär" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Sänd verifiering igen" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Ta bort" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Lägg till epost-adress" #: templates/account/email.html:70 msgid "Add Email" msgstr "Lägg till epost" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Vill du verkligen ta bort den valda epost-adressen?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "Epost-adress" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your email has been confirmed." msgstr "Ditt lösenord har tagits bort." #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "epost-bekräftelse" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "User %(user_display)s at %(site_name)s has given this as an email " #| "address.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Användare %(user_display)s på %(site_name)s har angivit detta som sin epost-" "adress.\n" "\n" "Klicka på följande adress för att bekräfta att detta stämmer: " "%(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 #, fuzzy #| msgid "Confirm Email Address" msgid "Please Confirm Your Email Address" msgstr "Verifiera epost-adress" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "Ta bort" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "Logga in" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "Ditt lösenord är nu ändrat." #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "Lösenord (igen)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account at %(site_domain)s.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Du har fått detta mail för att du eller någon annan har begärt en " "återställning av ditt lösenord på %(site_domain)s.\n" "Du kan bortse från detta mail om du inte begärt en återställning. Klicka på " "länken nedan för att återställa ditt lösenord." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Ditt användarnamn är %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Återställning av lösenord" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been reset." msgstr "Ditt lösenord har tagits bort." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Återställning av lösenord" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been set." msgstr "Ditt lösenord har tagits bort." #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "Återställning av lösenord" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "Konto" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "Epost-adresser" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "Nuvarande lösenord" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 #, fuzzy #| msgid "Your primary email address must be verified." msgid "Your email address is still pending verification." msgstr "Din primära epost-adress måste verifieras." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "Epost" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "Epost" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Verifiera epost-adress" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Verifiera att %(email)s är en epost-adress " "för %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "Tredjeparts-kontot är redan knutet till ett annat konto." #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Länken för att verifiera epost-adressen har förfallit eller är ogiltig. Skapa en ny epost-verification." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "Har du redan ett konto? Då kan du %(link)slogga in%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Logga ut" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Är du säker att du vill logga ut?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Du kan inte ta bort din primära epost-adress (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Verifierings-mail skickat till %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Du har verifierat %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Ta bort epost-adress %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Du har loggat in som %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Du har loggat ut." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Lösenordet ändrat." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Lösenord skapat." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Primär epost-adress satt." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Ändra lösenord" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Glömt lösenordet?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Glömt ditt lösenord? Ange din epost-adress nedan så skickar vi ett mail med " "instruktioner för att återställa det." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Återställ mitt lösenord" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Vänligen kontakta oss om du har problem med att återställa ditt lösenord." #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Vi har skickat ett mail till dig för\n" "verifiering. Klicka på länken inne i detta mail. Kontakta\n" "oss om det inte dyker upp inom ett par minuter." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Felaktig nyckel" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Länken för att återställa lösenordet var ogiltig, möjligtvis för att den " "redan har använts. Begär en ny lösenords-" "återställning." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Ditt lösenord är nu ändrat." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Skapa lösenord" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "Glömt lösenordet?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Skapa konto" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Skapa konto" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "Har du redan ett konto? Då kan du %(link)slogga in%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Skapa konto" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Anmälan stängd" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Tyvärr är anmälan stängd för närvarande." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Information" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "du är inloggad som %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Varning:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Du har inte angett någon epost-adress. Du borde lägga till en epost-adress " "så du kan få meddelanden, återställa ditt lösenord och liknande." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Verifiera din epost-adress" #: templates/account/verification_sent.html:12 #, fuzzy msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Ett mail för verifiering har skickats till %(email)s. Klicka på länken i mailet för att slutföra " "anmälan. Kontakta oss om det inte dyker upp inom ett par minuter." #: templates/account/verified_email_required.html:13 #, fuzzy #| msgid "" #| "This part of the site requires us to verify that\n" #| "you are who you claim to be. For this purpose, we require that you\n" #| "verify ownership of your e-mail address. " msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "För att få tillgång till denna avdelning måste du verifiera att\n" "du är den du säger att du är. Du måste därför bevisa att du\n" "angett rätt epost-adress. " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Vi har skickat ett mail till dig för\n" "verifiering. Klicka på länken inne i detta mail. Kontakta\n" "oss om det inte dyker upp inom ett par minuter." #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "Information: du kan fortfarande ändra din epost-adress." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Anslutna tredjeparts-konton" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "A security key has been removed." msgstr "Ditt lösenord har tagits bort." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" msgstr[1] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "Är du säker att du vill logga ut?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "Ej verifierad" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "Nuvarande lösenord" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "Fel vid tredjeparts-inloggning" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Ett fel inträffade vid inloggning via tredjeparts-konto." #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Du kan logga in på ditt konto via något av följande tredjeparts-konton:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "Du har för närvarande inga tredjeparts-konton knutna till ditt konto." #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "Lägg till tredjeparts-konto" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "Lägg till tredjeparts-konto" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "Lägg till tredjeparts-konto" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Inloggning avbruten" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Du valde att avbryta inloggningen via ett av dina tredjeparts-konton. Om " "detta var ett misstag kan du logga in igen." #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy #| msgid "The social account has been connected." msgid "The third-party account has been connected." msgstr "Tredjeparts-kontot har knutits till ditt kontot." #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy #| msgid "The social account has been disconnected." msgid "The third-party account has been disconnected." msgstr "Tredjeparts-kontot har tagits bort." #: templates/socialaccount/signup.html:12 #, fuzzy, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Du håller på att logga in via ditt konto på %(provider_name)s på \n" "%(site_name)s. Fyll i följande formulär för att slutföra inloggningen:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "Epost-adresser" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "Nuvarande lösenord" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Anslutna tredjeparts-konton" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Lösenordet måste vara minst {0} tecken långt" #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Du har fått detta mail för att du eller någon annan har begärt en " #~ "återställning av ditt lösenord på %(site_domain)s.\n" #~ "Du kan bortse från detta mail om du inte begärt en återställning. Klicka " #~ "på länken nedan för att återställa ditt lösenord." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Följande epost-adresser är knutna till ditt konto:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "Verifiera epost-adress" #, fuzzy, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "Logga in med ett\n" #~ "av dina befintliga tredjeparts-konton eller skapa ett konto \n" #~ "för %(site_name)s och logga in nedan:" #~ msgid "or" #~ msgstr "eller" #~ msgid "change password" #~ msgstr "ändra lösenord" #~ msgid "OpenID Sign In" #~ msgstr "Inloggning via OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "Denna epost-adress är redan knuten till ett annat konto" #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Ett mail har nu skickats. Kontakta oss om det inte dyker upp inom ett par " #~ "minuter." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Inloggningen och/eller lösenordet är felaktigt." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "" #~ "Användarnamn kan endast innehålla bokstäver, siffror samt @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Användarnamnet är upptaget. Välj ett annat." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Logga in" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "Du har verifierat att %(email)s är en " #~ "epost-adress för %(user_display)s." #~ msgid "Thanks for using our site!" #~ msgstr "Tack för att du använder vår hemsida!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Epost-bekräftelse skickad till %(email)s" #~ msgid "Delete Password" #~ msgstr "Ta bort lösenordet" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "Du kan ta bort ditt lösenord eftersom du är inloggad via OpenID." #~ msgid "delete my password" #~ msgstr "ta bort mitt lösenord" #~ msgid "Password Deleted" #~ msgstr "Lösenordet borttaget" django-allauth-65.0.2/allauth/locale/th/000077500000000000000000000000001467545753200200245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/th/LC_MESSAGES/000077500000000000000000000000001467545753200216115ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/th/LC_MESSAGES/django.po000066400000000000000000002145511467545753200234230ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Nattaphoom Chaipreecha, 2015 # msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-11 08:09+0000\n" "Last-Translator: Napapat Angsutrarux \n" "Language-Team: Thai \n" "Language: th\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "บัญชีนี้อยู่ในสถานะที่ใช้งานไม่ได้" #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "คุณไม่สามารถลบที่อยู่อีเมลหลักของคุณได้" #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "อีเมลนี้ได้ถูกเชื่อมกับบัญชีนี้แล้ว" #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "อีเมลและ/หรือรหัสผ่านที่ระบุมาไม่ถูกต้อง" #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "ชื่อผู้ใช้ได้ถูกลงทะเบียนด้วยอีเมลนี้แล้ว" #: account/adapter.py:62 msgid "Please type your current password." msgstr "โปรดใส่รหัสผ่านปัจจุบัน" #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "รหัสไม่ถูกต้อง" #: account/adapter.py:64 msgid "Incorrect password." msgstr "รหัสปัจจุบันรหัสผ่านไม่ถูกต้อง" #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "รหัสไม่ถูกต้องหรือหมดอายุ" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "token ที่ใช้รีเซ็ทรหัสผ่านไม่ถูกต้อง" #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "บัญชีของคุณไม่มีการยืนยัน ไม่สามารถเพิ่มที่อยู่อีเมลมากกว่า %d รายการ" #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "พยายามเข้าสู่ระบบล้มเหลวหลายครั้งเกินไป ลองอีกครั้งในภายหลัง" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "อีเมลนี้ไม่ได้เชื่อมกับบัญชีใดเลย" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "อีเมลหลักของคุณต้องได้การยืนยัน" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "ไม่สามารถใช้ชื่อผู้ใช้นี้ได้ กรุณาใช้ชื่อผู้ใช้อื่น" #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "ชื่อผู้ใช้และ/หรือรหัสผ่านที่ระบุมาไม่ถูกต้อง" #: account/adapter.py:741 msgid "Use your password" msgstr "ใช้รหัสผ่านของคุณ" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "ใช้แอปหรือรหัสยืนยันตัวตน" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "ใช้คีย์ความปลอดภัย" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "อีเมลหลักของคุณต้องได้การยืนยัน" #: account/apps.py:11 msgid "Accounts" msgstr "บัญชี" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "ต้องพิมพ์รหัสผ่านเดิมซ้ำอีกครั้ง" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "รหัสผ่าน" #: account/forms.py:93 msgid "Remember Me" msgstr "จดจำการเข้าใช้" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "อีเมล" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "อีเมล" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "ชื่อผู้ใช้" #: account/forms.py:123 msgid "Username or email" msgstr "ชื่อผู้ใช้ หรือ อีเมล" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "ลงชื่อเข้าใช้" #: account/forms.py:137 msgid "Forgot your password?" msgstr "ลืมรหัสผ่านของคุณ?" #: account/forms.py:299 msgid "Email (again)" msgstr "อีเมล์ (ไม่บังคับ)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "การยืนยันที่อยู่อีเมล" #: account/forms.py:311 msgid "Email (optional)" msgstr "อีเมล (ไม่จำเป็น)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "คุณจะต้องพิมพ์รหัสผ่านอีเมลเดียวกันทุกครั้ง" #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "รหัสผ่าน (อีกครั้ง)" #: account/forms.py:554 msgid "Current Password" msgstr "รหัสผ่านปัจจุบัน" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "รหัสผ่านใหม่" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "รหัสผ่านใหม่ (อีกครั้ง)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "รหัส" #: account/models.py:26 msgid "user" msgstr "ผู้ใช้" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "อีเมล" #: account/models.py:34 msgid "verified" msgstr "ยืนยันแล้ว" #: account/models.py:35 msgid "primary" msgstr "หลัก" #: account/models.py:41 msgid "email addresses" msgstr "อีเมล" #: account/models.py:150 msgid "created" msgstr "สร้างแล้ว" #: account/models.py:151 msgid "sent" msgstr "ส่งแล้ว" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "คีย์" #: account/models.py:157 msgid "email confirmation" msgstr "การยืนยันอีเมล" #: account/models.py:158 msgid "email confirmations" msgstr "การยืนยันอีเมล" #: headless/apps.py:7 msgid "Headless" msgstr "หัวขาด" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "คุณไม่สามารถเพิ่มที่อยู่อีเมลลงในบัญชีที่ได้รับการป้องกันโดยการรับรองความถูกต้องด้วยสองปัจจัย" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "คุณไม่สามารถปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยได้" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "คุณไม่สามารถสร้างรหัสกู้คืนได้โดยไม่ต้องเปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัย" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "คุณไม่สามารถเปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยได้จนกว่าคุณจะยืนยันที่อยู่อีเมลของคุณแล้ว" #: mfa/adapter.py:141 msgid "Master key" msgstr "มาสเตอร์คีย์" #: mfa/adapter.py:143 msgid "Backup key" msgstr "คีย์สำรอง" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "หมายเลขคีย์ {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA" #: mfa/models.py:24 msgid "Recovery codes" msgstr "รหัสการกู้คืน" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "เครื่องยืนยันตัวตน TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "รหัสตรวจสอบความถูกต้อง" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "ไร้รหัสผ่าน" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "การเปิดใช้งานการทำงานแบบไร้รหัสผ่านทำให้คุณสามารถลงชื่อเข้าใช้โดยใช้เพียงคีย์นี้ " "แต่ต้องมีข้อกำหนดเพิ่มเติม เช่น ไบโอเมตริกซ์หรือการป้องกัน PIN" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "มีบัญชีที่ใช้อีเมลนี้แล้ว โปรดลงชื่อเข้าใช้บัญชีนั้นก่อน จากนั้นเชื่อมต่อกับบัญชี %s ของคุณ" #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "โทเค็นไม่ถูกต้อง TInvalid" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "บัญชีของคุณไม่ได้ตั้งรหัสผ่านไว้" #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "บัญชีของคุณไม่มีอีเมลที่ยืนยันแล้ว" #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "" "คุณสามารถลงชื่อเข้าใช้บัญชีของคุณได้โดยใช้วิธีต่อไปนี้: " "ไม่ตัดการเชื่อมต่อบัญชีบุคคลที่สามที่เหลืออยู่ล่าสุดของคุณ:" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "บัญชีบุคคลที่สามของ Social เชื่อมโยงกับบัญชีอื่นอยู่แล้ว" #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "บัญชีโซเชียล" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "ผู้ให้บริการ" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ผู้ให้บริการ ไอดี" #: socialaccount/models.py:56 msgid "name" msgstr "ชื่อ" #: socialaccount/models.py:58 msgid "client id" msgstr "รหัสลูกค้า" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "รหัสแอปหรือรหัสผู้บริโภค" #: socialaccount/models.py:63 msgid "secret key" msgstr "รหัสลับ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "ความลับของ API, ความลับของไคลเอ็นต์ หรือความลับของผู้บริโภค" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "คีย์" #: socialaccount/models.py:81 msgid "social application" msgstr "การประยุกต์ใช้ทางสังคม" #: socialaccount/models.py:82 msgid "social applications" msgstr "การประยุกต์ใช้ทางสังคม" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "เข้าสู่ระบบครั้งล่าสุด" #: socialaccount/models.py:120 msgid "date joined" msgstr "วันที่เข้าร่วม" #: socialaccount/models.py:121 msgid "extra data" msgstr "ข้อมูลเพิ่มเติม" #: socialaccount/models.py:125 msgid "social account" msgstr "บัญชีโซเชียล" #: socialaccount/models.py:126 msgid "social accounts" msgstr "บัญชีโซเชียล" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) หรือโทเค็นการเข้าถึง (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "ความลับของโทเค็น" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) หรือรีเฟรชโทเค็น (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "หมดอายุเมื่อ" #: socialaccount/models.py:174 msgid "social application token" msgstr "โทเค็นแอปพลิเคชันโซเชียล" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "โทเค็นแอปพลิเคชันโซเชียล" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "ข้อมูลโปรไฟล์ไม่ถูกต้อง" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "ลงชื่อเข้าใช้" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "ยกเลิก" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "การตอบสนองไม่ถูกต้องขณะได้รับคำขอโทเค็นจาก \"%s\" การตอบสนองคือ: %s" #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "การตอบสนองผิดพลาดขณะที่กำลังได้รับ access token จาก \"%s\"" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "ไม่มีการบันทึก request token ของ \"%s\"" #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "ไม่มีการบันทึก access token ของ \"%s\"" #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "ไม่มีสิทธิ์การเข้าใช้ทรัพยากรส่วนตัว ที่ \"%s\"" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "การตอบสนองผิดพลาดขณะที่กำลังได้รับ request token จาก \"%s\"" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "บัญชีไม่มีการใช้งาน" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "บัญชีนี้ไม่มีการใช้งาน" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "ยืนยันที่อยู่อีเมล AddrAccess" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "โปรดตรวจสอบสิทธิ์อีกครั้งเพื่อปกป้องบัญชีของคุณ" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "ทางเลือกอื่น" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "ยืนยันอีเมล์" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "กรอกรหัสยืนยันอีเมล" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "เราส่งรหัสไปที่ %(email_link)s รหัสจะหมดอายุในไม่ช้า โปรดกรอกรหัสโดยเร็ว" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "ยืนยัน" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "ลงชื่อเข้าใช้" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "ป้อนรหัสเข้าสู่ระบบ" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "อีเมล" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "อีเมลต่อไปนี้ ได้เชื่อมกับบัญชีของคุณ" #: templates/account/email.html:25 msgid "Verified" msgstr "ยืนยันแล้ว" #: templates/account/email.html:29 msgid "Unverified" msgstr "ยังไม่ได้ยืนยัน" #: templates/account/email.html:34 msgid "Primary" msgstr "หลัก" #: templates/account/email.html:44 msgid "Make Primary" msgstr "ทำให้เป็นอันหลัก" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "ส่งการยืนยันอีกครั้ง" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "ลบ" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "เพิ่มอีเมล" #: templates/account/email.html:70 msgid "Add Email" msgstr "เพิ่มอีเมล" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "คุณต้องการที่จะลบอีเมลนี้จริงหรอ" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "คุณได้รับอีเมลนี้ เพราะคุณหรือมีคนอื่นพยายามลงทะเบียน\n" "บัญชีโดยใช้ที่อยู่อีเมล:\n" "\n" "%(email)s\n" "\n" "อย่างไรก็ตาม มีบัญชีที่ใช้อีเมลดังกล่าวอยู่แล้ว ในกรณีที่คุณ\n" "ลืมอีเมลนี้ไป โปรดใช้ขั้นตอนลืมรหัสผ่านเพื่อกู้คืน\n" "บัญชีของคุณ:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "มีบัญชีอยู่แล้ว" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "สวัสดีจาก %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "ขอบคุณที่ใช้บริการของ %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "คุณได้รับอีเมลนี้ เนื่องจากมีการเปลี่ยนแปลงต่อไปนี้กับบัญชีของคุณ" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "หากคุณไม่รู้จักการเปลี่ยนแปลงนี้ โปรดดำเนินการตามมาตรการรักษาความปลอดภัยที่เหมาะสมทันที " "การเปลี่ยนแปลงในบัญชีของคุณมีต้นตอมาจาก:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "อีเมล์ของคุณถูกเปลี่ยนจาก %(from_email)s to %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "ที่อยู่อีเมลเปลี่ยนแปลง" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "คุณได้ทำการยืนยัน %(email)s" #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "การยืนยันทางอีเมล์" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "คุณได้รับอีเมลนี้เพราะผู้ใช้ %(user_display)s ให้ที่อยู่อีเมลของคุณเพื่อลงทะเบียนบัญชีใน " "%(site_domain)s" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "รหัสยืนยันอีเมลของคุณแสดงอยู่ด้านล่างนี้ โปรดป้อนรหัสดังกล่าวในหน้าต่างเบราว์เซอร์ที่เปิดอยู่" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "เพื่อยืนยันว่าถูกต้อง โปรดไปที่ %(activate_url)s" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "กรุณายืนยันอีเมลของคุณ" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "ที่อยู่อีเมล %(deleted_email)s ถูกลบออกจากบัญชีของคุณ" #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "ลบ อีเมล์" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "รหัสลงชื่อเข้าใช้ของคุณแสดงอยู่ด้านล่างนี้ โปรดป้อนรหัสดังกล่าวในหน้าต่างเบราว์เซอร์ที่เปิดอยู่" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "คุณสามารถละเว้นเมลนี้ได้อย่างปลอดภัยหากคุณไม่ได้เป็นผู้เริ่มดำเนินการนี้" #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "ลงชื่อเข้าใช้" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "รหัสผ่านของคุณได้เปลี่ยนแล้ว" #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "รหัสผ่าน (อีกครั้ง)" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "สวัสดีจาก %(site_name)s!\n" "\n" "You're receiving this e-mail because you or someone else has requested a " "คุณได้รับอีเมลนี้เพราะว่า คุณหรือใครบางคนได้ทำการร้องขอรหัสผ่านของบัญชีนี้ที่ %(site_domain)s.\n" "It can be safely ignored if you did not request a password reset. Click the " "คุณสามารถมองข้ามและลบอีเมลนี้ทิ้งได้เลยหากคุณไม่ได้ทำการร้องขอการรีเซ็ทรหัสผ่านคลิกที่ลิงค์ข้างล่างนี้เพื่อรีเซ็ทรหัสผ่านของคุณ" #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "ในกรณีเผื่อคุณลืม ชื่อผู้ใช้ของคุณคือ %(username)s" #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "อีเมลในการรีเซ็ทรหัสผ่าน" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "รหัสผ่านของคุณได้ถูกเปลี่ยนและรีเซ็ตแล้ว" #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "รีเซ็ทรหัสผ่าน" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "รหัสผ่านของคุณได้เปลี่ยนแล้ว" #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "รีเซ็ทรหัสผ่าน" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "คุณได้รับอีเมลนี้เนื่องจากคุณหรือบุคคลอื่นพยายามเข้าถึงบัญชีที่มีอีเมล %(email)s อย่างไรก็ตาม " "เราไม่มีบันทึกเกี่ยวกับบัญชีดังกล่าวในฐานข้อมูลของเรา" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "หากเป็นคุณ คุณสามารถลงทะเบียนบัญชีโดยใช้ลิงก์ด้านล่าง" #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "ไม่ทราบ บัญชี" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "ที่อยู่อีเมล" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "รหัสผ่านอีเมลปัจจุบัน" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "เปลี่ยนเป็น" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "ที่อยู่อีเมลหลักของคุณยังต้องอยู่ระหว่างรอการยืนยัน" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "ยกเลิกการเปลี่ยนแปลง" #: templates/account/email_change.html:49 msgid "Change to" msgstr "อีเมล์เปลี่ยนเป็น" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "เปลี่ยนอีเมล์" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "ยืนยันอีเมล" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "กรุณายืนยันว่า %(email)s เป็นที่อยู่อีเมลของผู้ใช้ " "%(user_display)s" #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "ไม่สามารถยืนยัน %(email)s ได้เพราะได้รับการยืนยันโดยบัญชีอื่นแล้ว" #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "ลิงก์ยืนยันอีเมลนี้หมดอายุหรือไม่ถูกต้อง กรุณา ส่งคำขอยืนยันอีเมลใหม่" #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "ถ้าหากคุณยังไม่มีบัญชี, กรุณา %(link)sลงทะเบียน%(end_link)sก่อน." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "ลงชื่อเข้าใช้ด้วยรหัสผ่าน" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "ส่งรหัสลงชื่อเข้าใช้ให้ฉันทางอีเมล์" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "ลงชื่อออก" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "คุณแน่ใจหรือว่าต้องการจะลงชื่อออก" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "คุณไม่สามารถลบอีเมลของคุณได้ (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "อีเมลยืนยันได้ถูกส่งไปที่ %(email)s" #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "คุณได้ทำการยืนยัน %(email)s" #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "ลบอีเมล %(email)s แล้ว" #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s ลงชื่อเข้าใช้สำเร็จ" #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "คุณได้ออกจากระบบแล้ว" #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "รหัสลงชื่อเข้าใช้ได้ถูกส่งไปยัง %(email)s แล้ว" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "เปลี่ยนรหัสผ่านสำเร็จ" #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "ตั้งรหัสผ่านสำเร็จ" #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "ตั้งอีเมลหลักสำเร็จ" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "เปลี่ยนรหัสผ่าน" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "ลืมรหัสผ่าน?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "ลืมรหัสผ่านหรือไม่? ป้อนที่อยู่อีเมลของคุณด้านล่าง และเราจะส่งอีเมลไปให้คุณเพื่อรีเซ็ตรหัสผ่าน" #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "รีเซ็ทรหัสผ่านของฉัน" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "กรุณาติดต่อเราหากคุณพบปัญหาในการรีเซ็ทรหัสผ่าน" #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "เราได้ส่งอีเมลถึงคุณแล้ว หากต้องการยืนยันตัวตน โปรดคลิกลิงก์ในอีเมลนี้ โปรดไปที่โฟลเดอร์สแปม " "มิฉะนั้น โปรดติดต่อเราหากไม่ได้รับอีเมลภายในไม่กี่นาที" #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Token เสีย" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "ลิงค์ที่ใช้ในการรีเซ็ทรหัสผ่านไม่ถูกต้อง อาจเป็นไปได้ว่ามันได้ถูกใช้ไปแล้วกรุณาร้องขอ การรีเซ็ทรหัสผ่านใหม่" #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "รหัสผ่านของคุณได้เปลี่ยนแล้ว" #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "ตั้งรหัสผ่าน" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "ลืมรหัสผ่าน?:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "คุณจะได้รับอีเมลที่มีรหัสพิเศษสำหรับการลงชื่อเข้าใช้แบบไม่ต้องใช้รหัสผ่าน" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "ขอรหัส" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "ตัวเลือกการลงชื่อเข้าใช้อื่นๆ" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "ลงทะเบียน" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "ลงทะเบียน" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "มีบัญชีอยู่แล้ว? กรุณา%(link)sลงชื่อเข้าใช้%(end_link)s" #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "ลงชื่อเข้าใช้ด้วยรหัสผ่าน" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "ลงทะเบียน" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "ตัวเลือกการลงชื่อเข้าใช้อื่นๆ" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "การลงทะเบียนปิดอยู่" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "เราขอโทษด้วย การลงทะเบียนได้ปิดชั่วคราว" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "หมายเหตุ" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "คุณเข้าสู่ระบบแล้วในชื่อ %(user_display)s" #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "คำเตือน:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "ขณะนี้คุณยังไม่ได้ตั้งค่าที่อยู่อีเมล คุณควรเพิ่มที่อยู่อีเมลเพื่อรับการแจ้งเตือน รีเซ็ตรหัสผ่าน ฯลฯ" #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "ยืนยันอีเมลของคุณ" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "เราได้ส่งอีเมลถึงคุณเพื่อยืนยันแล้ว ทำตามลิงก์ที่ให้ไว้เพื่อดำเนินการลงทะเบียนให้เสร็จสิ้น " "หากคุณไม่พบอีเมลยืนยันในกล่องจดหมายหลัก โปรดตรวจสอบในโฟลเดอร์สแปม " "โปรดติดต่อเราหากคุณไม่ได้รับอีเมลยืนยันภายในไม่กี่นาที" #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "ส่วนนี้ของไซต์ต้องการให้เราตรวจสอบว่าคุณคือบุคคลที่คุณอ้างว่าเป็น เพื่อจุดประสงค์นี้ " "เราต้องการให้คุณ\n" "ยืนยันความเป็นเจ้าของที่อยู่อีเมลของคุณ " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "เราได้ส่งอีเมลถึงคุณเพื่อยืนยันแล้ว โปรดคลิกลิงก์ในอีเมลนี้ โปรดส่งอีเมล " "หากคุณไม่พบอีเมลยืนยันในกล่องจดหมายหลัก โปรดตรวจสอบในโฟลเดอร์สแปม มิฉะนั้น " "โปรดติดต่อเราหากไม่ได้รับอีเมลภายในไม่กี่นาที" #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "หมายเหตุ: คุณยังสามารถเปลี่ยนที่อยู่อีเมลของคุณได้" #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "ข้อความ:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "เมนู:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "การเชื่อมต่อบัญชีต่างๆ" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "การตรวจสอบสิทธิ์สองปัจจัย" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "เซสชั่น" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "บัญชีของคุณได้รับการปกป้องด้วยการตรวจสอบสิทธิ์สองขั้นตอน โปรดป้อนรหัสตรวจสอบสิทธิ์:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "มีการสร้างรหัสการกู้คืนการตรวจสอบสิทธิ์แบบสองปัจจัยชุดใหม่แล้ว" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "รหัสการกู้คืนใหม่ถูกสร้างขึ้น" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "เปิดใช้งานแอปพลิเคชัน Authenticator แล้ว" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "เปิดใช้งานแอป Authenticator แล้ว" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "ปิดใช้งานแอปพลิเคชัน Authenticator แล้ว" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "ปิดใช้งานแอป Authenticator แล้ว" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "มีการเพิ่มคีย์ความปลอดภัยใหม่แล้ว" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "เพิ่มรหัสความปลอดภัยแล้ว" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "คุณได้ยืนยันแล้วว่า %(email)sรหัสความปลอดภัยถูกลบออกแล้ว" #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "ถอดคีย์ความปลอดภัยออกแล้ว" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Authenticator แอป" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "การยืนยันตัวตนโดยใช้แอปพลิเคชันการยืนยันตัวตนเปิดใช้งานอยู่" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "แอปพลิเคชันการตรวจสอบสิทธิ์ไม่ได้เปิดใช้งาน" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "ปิดการใช้งาน" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "เปิดใช้งาน" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "กุญแจความปลอดภัย" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "คุณได้เพิ่มรหัสความปลอดภัย %(count)s แล้ว" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "ไม่มีการเพิ่มคีย์ความปลอดภัย" #: templates/mfa/index.html:62 msgid "Manage" msgstr "จัดการ" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "แอป" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "รหัสการกู้คืน" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "มีรหัสกู้คืน %(unused_count)s จากทั้งหมด %(total_count)s รหัส" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "ไม่มีการตั้งค่ารหัสการกู้คืน" #: templates/mfa/index.html:96 msgid "View" msgstr "ดู" #: templates/mfa/index.html:102 msgid "Download" msgstr "ดาวน์โหลด" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "สร้าง" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "มีการสร้างชุดรหัสการกู้คืนใหม่แล้ว" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "เพิ่มคีย์ความปลอดภัยแล้ว" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "ถอดคีย์ความปลอดภัยออกแล้ว" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "กรอกรหัสยืนยันตัวตน:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "คุณกำลังจะสร้างชุดรหัสการกู้คืนใหม่สำหรับบัญชีของคุณ" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "การดำเนินการนี้จะทำให้รหัสที่มีอยู่ของคุณไม่ถูกต้อง" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "คุณแน่ใจมั้ย?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "รหัสที่ไม่ได้ใช้" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "รหัสดาวน์โหลด" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "สร้างรหัสใหม่" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "เปิดใช้งานแอป Authenticator" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "หากต้องการปกป้องบัญชีของคุณด้วยการตรวจสอบสิทธิ์สองขั้นตอน ให้สแกนรหัส QR " "ด้านล่างด้วยแอปตรวจสอบสิทธิ์ของคุณ จากนั้นป้อนรหัสยืนยันที่สร้างโดยแอปด้านล่าง" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "ความลับของผู้รับรอง" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "คุณสามารถเก็บความลับนี้ไว้และนำไปใช้ในการติดตั้งแอปพลิเคชันการตรวจสอบความถูกต้องอีกครั้งในภายหลังได้" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "ปิดใช้งานแอป Authenticator" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "คุณกำลังจะปิดการใช้งานการตรวจสอบสิทธิ์โดยใช้แอปตัวตรวจสอบสิทธิ์ คุณแน่ใจหรือไม่?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "เพิ่มรหัสความปลอดภัย" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "ถอดกุญแจความปลอดภัยออก" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "คุณแน่ใจว่าต้องการลงชื่อออกหรือลบคีย์ความปลอดภัยนี้หรือไม่" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "การใช้งาน" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "กุญแจผี" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "กุญแจความปลอดภัย" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "คีย์นี้ไม่ได้ระบุว่าเป็นรหัสผ่านหรือไม่" #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "ไม่ระบุ" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "เพิ่มเมื่อ %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "ใช้ล่าสุด %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "แก้ไข" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "แก้ไขรหัสความปลอดภัย" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "บันทึก" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "กุญแจผี" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "สร้างแล้ว" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "ฟังก์ชันนี้ต้องใช้ JavaScript" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "การเข้าสู่ระบบของบุคคลที่สามในเครือข่ายสังคมออนไลน์ล้มเหลว" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "เกิดข้อผิดพลาดขณะพยายามเข้าสู่ระบบผ่านเครือข่ายโซเชียลหรือบัญชีบุคคลที่สามของคุณ" #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "คุณสามารถลงชื่อเข้าใช้บัญชีของคุณโดยใช้บัญชีบุคคลที่สามต่อไปนี้:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "ขณะนี้คุณไม่มีบัญชีบุคคลที่สามหรือเครือข่ายโซเชียลที่เชื่อมโยงกับบัญชีนี้" #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "เพิ่มบัญชีบุคคลที่สาม" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "บัญชีบุคคลที่สามจาก %(provider)s เชื่อมต่อกับบัญชีของคุณแล้ว" #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "เพิ่มบัญชีบุคคลที่สามที่เชื่อมต่อ" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "บัญชีบุคคลที่สามจาก %(provider)s ถูกตัดการเชื่อมต่อจากบัญชีของคุณ" #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "เพิ่มบัญชีบุคคลที่สามที่ถูกตัดการเชื่อมต่อ" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "เชื่อมต่อ %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "คุณกำลังจะเชื่อมต่อบัญชีบุคคลที่สามใหม่จาก %(provider)s" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "ลงชื่อเข้าใช้ผ่าน %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "คุณกำลังจะลงชื่อเข้าใช้โดยใช้บัญชีบุคคลที่สามจาก %(provider)s" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "ดำเนินการต่อ" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "การลงชื่เข้าใช้ยกเลิก" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "คุณตัดสินใจที่จะยกเลิกการลงชื่อเข้าใช้เว็บของเราด้วยหนึ่งในบัญชีของคุณถ้านี้เป็นความผิดพลาด กรุณาลงชื่อเข้าใช้" #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "บัญชีบุคคลที่สามของ Social ได้รับการเชื่อมโยงแล้ว" #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "บัญชีบุคคลที่สามของ Social ถูกตัดการเชื่อมต่อ" #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "คุณกำลังจะทำการใช้บัญชี %(provider_name)s ของคุณ ในการเข้าสู่ระบบของ\n" "%(site_name)s. ในขั้นตอนสุดท้าย กรุณากรอกฟอร์มข้างล่าง:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "หรือใช้บุคคลที่สาม" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "ออกจากระบบจากเซสชันอื่นทั้งหมด" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "เริ่มต้นที่" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "อีเมล์ที่อยู่ IP" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "บราวเซอร์" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "พบเห็นครั้งสุดท้ายเมื่อ" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "รหัสผ่านปัจจุบัน" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "ออกจากระบบเซสชั่นอื่น ๆ" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "เซสชันผู้ใช้" #: usersessions/models.py:92 msgid "session key" msgstr "คีย์เซสชั่น" #~ msgid "Account Connection" #~ msgstr "การเชื่อมต่อบัญชี" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "รหัสผ่านต้องมีอย่างน้อย {0} ตัวอักษร" #, fuzzy, python-format #~| msgid "" #~| "Hello from %(site_name)s!\n" #~| "\n" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "สวัสดีจาก %(site_name)s!\n" #~ "\n" #~ "You're receiving this e-mail because you or someone else has requested a " #~ "คุณได้รับอีเมลนี้เพราะว่า คุณหรือใครบางคนได้ทำการร้องขอรหัสผ่านของบัญชีนี้ที่ " #~ "%(site_domain)s.\n" #~ "It can be safely ignored if you did not request a password reset. Click " #~ "the " #~ "คุณสามารถมองข้ามและลบอีเมลนี้ทิ้งได้เลยหากคุณไม่ได้ทำการร้องขอการรีเซ็ทรหัสผ่านคลิกที่ลิงค์ข้างล่างนี้เพื่อรีเซ็ทรหัสผ่านของคุณ" #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "อีเมลต่อไปนี้ได้เชื่อมกับบัญชีของคุณ" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "ยืนยันอีเมล" #, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "กรุณาลงชื่อเข้าใช้ด้วยบัญชีภายนอกของคุณ\n" #~ "หรือ Or, %(link)sลงทะเบียน %(end_link)s\n" #~ "สำหรับบัญชีของ %(site_name)s และลงชื่อเข้าใช้ด้านล่าง:" #~ msgid "or" #~ msgstr "sinv" #~ msgid "change password" #~ msgstr "เปลี่ยนรหัสผ่าน" #~ msgid "OpenID Sign In" #~ msgstr "ลงชื่อเข้าใช้ด้วย OpenID" #~ msgid "This email address is already associated with another account." #~ msgstr "อีเมลนี้ได้ถูกเชื่อมกับบัญชีอื่นแล้ว" #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "เราได้ส่งอีเมลให้คุณแล้ว. กรุณาติดต่อเราหากคุณไม่ได้รับอีเมลภายในเวลาไม่กี่นาทีนี้" #~ msgid "The login and/or password you specified are not correct." #~ msgstr "การลงชื่เข้าใช้และ/หรือรหัสผ่านที่ระบุมาไม่ถูกต้อง" #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "ชื่อผู้ใช้สามารถมีตัวอักษรภาษาอังกฤษตัวเลขและ @/./+/-/_. เท่านั้น" #~ msgid "This username is already taken. Please choose another." #~ msgstr "ชื่อผู้ใช้นี้ถูกใช้แล้ว กรุณาเลือกชื่ออื่น" #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "ลงชื่อเข้าใช้" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "คุณได้ยืนยันว่า %(email)s เป็นอีเมลของผู้ใช้ " #~ "%(user_display)s." django-allauth-65.0.2/allauth/locale/tr/000077500000000000000000000000001467545753200200365ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/tr/LC_MESSAGES/000077500000000000000000000000001467545753200216235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/tr/LC_MESSAGES/django.po000066400000000000000000001537011467545753200234340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # , 2013 msgid "" msgstr "" "Project-Id-Version: django-allauth\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-09-23 09:16+0000\n" "Last-Translator: Emirhan Soytaş \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.8-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Bu hesap şu anda etkin değil." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Birincil e-posta adresinizi kaldıramazsınız." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Bu e-posta adresi, halihazırda bu hesap ile ilişkilendirilmiş haldedir." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Girdiğiniz e-posta adresi ve/veya şifre doğru değil." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Bu e-posta adresiyle bir kullanıcı zaten kayıtlı." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Lütfen mevcut şifrenizi giriniz." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Hatalı kod." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Hatalı şifre." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Geçersiz veya süresi geçmiş anahtar." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Şifre sıfırlama kodu hatalı." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "%d adetten fazla e-posta adresi ekleyemezsiniz." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Çok fazla hatalı giriş yapıldı. Lütfen daha sonra tekrar deneyin." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Bu e-posta adresi hiçbir kullanıcı hesabıyla ilişkili değil" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Birincil e-posta adresinizin doğrulanması gerekmektedir." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "Bu kullanıcı adı kullanılamaz. Lütfen başka bir kullanıcı adı deneyin." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Girdiğiniz kullanıcı adı ve/veya şifre doğru değil." #: account/adapter.py:741 msgid "Use your password" msgstr "Şifrenizi kullanın" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Doğrulayıcı uygulaması veya kodu kullan" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Güvenlik anahtarı kullan" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Seçili e-posta adreslerini doğrulanmış olarak işaretle" #: account/apps.py:11 msgid "Accounts" msgstr "Hesaplar" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Her sefer için aynı şifreyi girmelisiniz." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Şifre" #: account/forms.py:93 msgid "Remember Me" msgstr "Beni Hatırla" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "E-posta adresi" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "E-posta" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Kullanıcı adı" #: account/forms.py:123 msgid "Username or email" msgstr "Kullanıcı adı ya da e-posta adresi" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Giriş Yap" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Şifrenizi mi unuttunuz?" #: account/forms.py:299 msgid "Email (again)" msgstr "E-posta adresi (tekrar)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "E-posta adresi doğrulama" #: account/forms.py:311 msgid "Email (optional)" msgstr "E-posta adresi (zorunlu değil)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Her sefer için aynı e-posta adresini girmelisiniz." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Şifre (tekrar)" #: account/forms.py:554 msgid "Current Password" msgstr "Mevcut Şifre" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Yeni Şifre" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Yeni Şifre (tekrar)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kod" #: account/models.py:26 msgid "user" msgstr "kullanıcı" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "e-posta adresi" #: account/models.py:34 msgid "verified" msgstr "doğrulanmış" #: account/models.py:35 msgid "primary" msgstr "birincil" #: account/models.py:41 msgid "email addresses" msgstr "e-posta adresleri" #: account/models.py:150 msgid "created" msgstr "oluşturuldu" #: account/models.py:151 msgid "sent" msgstr "gönderildi" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "anahtar" #: account/models.py:157 msgid "email confirmation" msgstr "e-posta onayı" #: account/models.py:158 msgid "email confirmations" msgstr "e-posta onayları" #: headless/apps.py:7 msgid "Headless" msgstr "Gözetimsiz" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "İki faktörlü kimlik doğrulama ile korunan bir hesaba e-posta adresi " "ekleyemezsiniz." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "İki faktörlü kimlik doğrulamayı devre dışı bırakamazsınız." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "İki faktörlü kimlik doğrulamayı aktif hale getirmeden kurtarma kodu " "oluşturamazsınız." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Doğrulanmış bir e-posta adresiniz olmadığı sürece iki faktörlü kimlik " "doğrulamayı etkinleştiremezsiniz." #: mfa/adapter.py:141 msgid "Master key" msgstr "Ana anahtar" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Yedek anahtar" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "{number} no.lu Anahtar" #: mfa/apps.py:9 msgid "MFA" msgstr "MFA(Çok Faktörlü Kimlik Doğrulama)" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Kurtarma kodları" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP(Zaman Tabanlı Tek Seferlik Parola) Doğrulayıcısı" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Doğrulayıcı kodu" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Şifresiz" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Şifresiz işlemi etkinleştirmek sadece bu anahtarı kullanarak giriş yapmanıza " "olanak sağlar fakat biyometri veya PIN koruması gibi ek gereksinimleri " "zorunlu kılar." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Bu e-posta adresi ile kayıtlı bir hesap bulunmaktadır. Lütfen önce bu hesaba " "giriş yapıp daha sonra %s adlı hesabınızı bağlayınız." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Geçersiz jeton." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Hesabınızda belirlenmiş herhangi bir şifre bulunmamaktadır." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Hesabınızın doğrulanmış e-posta adresi yok." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Kalan son üçüncü taraf hesabınızın bağlantısını kesemezsiniz." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Bu üçüncü taraf hesabı halihazırda farklı bir hesaba bağlıdır." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Sosyal Hesaplar" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "sağlayıcı" #: socialaccount/models.py:52 msgid "provider ID" msgstr "tedarikçi kimlik numarası" #: socialaccount/models.py:56 msgid "name" msgstr "isim" #: socialaccount/models.py:58 msgid "client id" msgstr "istemci kimlik numarası" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Uygulama kimlik numarası veya tüketici anahtarı" #: socialaccount/models.py:63 msgid "secret key" msgstr "gizli anahtar" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API anahtarı, istemci anahtarı veya tüketici anahtarı" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Anahtar" #: socialaccount/models.py:81 msgid "social application" msgstr "sosyal medya uygulaması" #: socialaccount/models.py:82 msgid "social applications" msgstr "sosyal medya uygulamaları" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "son giriş" #: socialaccount/models.py:120 msgid "date joined" msgstr "katıldığı tarih" #: socialaccount/models.py:121 msgid "extra data" msgstr "ek veri" #: socialaccount/models.py:125 msgid "social account" msgstr "sosyal hesap" #: socialaccount/models.py:126 msgid "social accounts" msgstr "sosyal hesaplar" #: socialaccount/models.py:160 msgid "token" msgstr "jeton" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) veya access token (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "jeton anahtarı" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) veya refresh token (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "geçersiz olma tarihi" #: socialaccount/models.py:174 msgid "social application token" msgstr "sosyal medya uygulaması jetonu" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "sosyal medya uygulaması jetonları" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Geçersiz profil bilgisi" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Giriş Yap" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Iptal" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "\"%s\"'dan istek jetonu temin edilirken geçersiz yanıt alındı. Yanıt %s idi." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "\"%s\"'dan erişim kodu alınırken geçersiz cevap alındı." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "\"%s\" için hiçbir talep kodu kaydedilmedi." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "\"%s\" için hiçbir erişim kodu kaydedilmedi." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\"'daki özel kaynaklara erişim yok." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "\"%s\"'dan talep kodu alınırken geçersiz cevap alındı." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Hesap Etkin Değil" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Bu hesap etkin değil." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Erişim Doğrulama" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Hesabınızı güvenilir hale getirmek için lütfen tekrar doğrulayın." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Alternatif seçenekler" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "E-Posta Onayı" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "E-Posta Onay Kodu Gir" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "%(email_link)s adresine bir kod gönderdik. Gönderilen kodun süresi kısa " "zamanda dolacağından dolayı lütfen hızlı davranınız." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Onayla" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Giriş Yap" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Giriş Kodunu Gir" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "E-posta Adresleri" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Şu e-posta adresleri hesabınızla ilişkilendirildi:" #: templates/account/email.html:25 msgid "Verified" msgstr "Doğrulanmış" #: templates/account/email.html:29 msgid "Unverified" msgstr "Doğrulanmamış" #: templates/account/email.html:34 msgid "Primary" msgstr "Birincil" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Birincil Yap" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Tekrar Doğrula" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Kaldır" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "E-posta Adresi Ekle" #: templates/account/email.html:70 msgid "Add Email" msgstr "E-posta Ekle" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Seçilen e-posta adresini kaldırmak istediğinizden emin misiniz?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Bu e-postayı, siz veya başka birisi aşağıdaki e-posta adresini kullanarak " "kayıt olmaya\n" "çalıştığı için alıyorsunuz:\n" "\n" "%(email)s\n" "\n" "Fakat, bu e-posta adresini kullanan bir hesap halihazırda mevcut " "durumdadır. Eğer unuttuysanız\n" "hesabınızı kurtarmak için lütfen şifre yenileme işleminden\n" "faydalanınız:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Hesap Halihazırda Mevcut" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "%(site_name)s'ten Merhaba!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "%(site_name)s'i kullandığınız için teşekkür ederiz!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "Bu e-postayı, hesabınızda bir değişiklik yapıldığı için alıyorsunuz:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Bu değişiklikten haberdar değilseniz lütfen gerekli güvenlik önlemlerini " "derhal alınız. Hesabınızdaki değişikliğin kaynağı alt kısımda " "belirtilmiştir:\n" "\n" "- IP adresi: %(ip)s\n" "- Tarayıcı: %(user_agent)s\n" "- Tarih: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" "%(from_email)s adlı e-posta adresiniz %(to_email)s şeklinde değiştirilmiştir." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "E-posta Adresi Değiştirildi" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "E-posta adresiniz onaylandı." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "E-Posta Adresi Onayı" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Bu e-postayı, %(user_display)s adlı kullanıcı, e-posta adresinizi " "%(site_domain)s üzerinde bir hesap oluşturmak adına kullandığı için " "alıyorsunuz." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "E-posta onay kodunuz alt kısımda belirtilmiştir. Kodu, açık olan tarayıcı " "sekmenize giriniz." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" "Bunun doğru olduğunu düşünüyorsanız %(activate_url)s adlı bağlantıyı ziyaret " "ediniz." #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Lütfen E-posta Adresinizi Onaylayın" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "%(deleted_email)s adlı e-posta adresi hesabınızdan kaldırılmıştır." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "E-Posta Adresi Kaldırıldı" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Giriş kodunuz alt kısımda belirtilmiştir. Kodu, açık olan tarayıcı sekmenize " "giriniz." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Alınan aksiyondan haberdar değilseniz bu e-postayı görmezden gelebilirsiniz." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Giriş Kodu" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Şifreniz değiştirildi." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Şifre Değiştirildi" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Bu e-postayı, siz veya başka biri, kullanıcı hesabınız için şifre sıfırlama " "talebinde bulunduğu için alıyorsunuz.\n" "Eğer şifre sıfırlama talebinde bulunan kişi siz değilseniz bu uyarıyı " "görmezden gelebilirsiniz. Şifrenizi sıfırlamak için aşağıdaki bağlantıya " "tıklayın." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Kullanıcı adınızı unuttuysanız, kullanıcı adınız: %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Şifre Sıfırlama E-postası" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Şifreniz sıfırlandı." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Şifre Sıfırlama" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Şifreniz belirlendi." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Şifre Tanımlandı" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Bu e-postayı, siz ya da başka biri %(email)s adlı e-posta adresini " "kullanarak bir hesaba giriş yapmaya çalıştığı için alıyorsunuz. Ancak, giriş " "yapmaya çalışılan hesaba dair veritabanımızda herhangi bir kayıt " "bulunmamaktadır." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Eğer o kişi siz iseniz aşağıdaki linki kullanarak bir hesap " "oluşturabilirsiniz." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Bilinmeyen Hesap" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "E-posta Adresi" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Mevcut e-posta" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Şuna değiştiriliyor" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "E-posta adresiniz hala onay aşamasındadır." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Değişikliği İptal Et" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Şuna değiştir" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "E-posta Adresini Değiştir" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "E-posta Adresi Doğrula" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Lütfen %(email)s adlı e-posta adresinin " "%(user_display)s kullanıcısına ait olduğunu onaylayın." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "%(email)s adlı e-posta adresi başka bir hesap tarafından doğrulandığı için " "onaylanamıyor." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Bu e-posta adresi onaylama bağlantısı sona ermiş veya geçersizdir. Lütfen yeni bir e-posta adresi doğrulama talebinde bulunun.." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Zaten hesabınız var mı? O zaman lütfen %(link)sgiriş yapın%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Geçiş anahtarı ile giriş yap" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Bana giriş kodu maili gönder" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Çıkış Yap" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Çıkış yapmak istediğinize emin misiniz?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "(%(email)s) adlı birincil e-posta adresinizi kaldıramazsınız." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Doğrulama e-posta'sı %(email)s adresine gönderildi." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s adresini onayladınız." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s adresini sildiniz." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s olarak başarıyla giriş yapıldı." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Çıkış yaptınız." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "%(email)s e-posta adresine bir giriş kodu gönderildi." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Şifre başarıyla değiştirildi." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Şifre başarıyla belirlendi." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Birincil e-posta adresi tanımlandı." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Şifre Değiştir" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Şifrenizi mi unuttunuz?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Şifrenizi mi unuttunuz? E-posta adresinizi aşağıya yazın ve size parolanızı " "sıfırlamanıza imkan veren bir e-posta gönderelim." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Şifremi Sıfırla" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Şifrenizi sıfırlarken herhangi bir sorunla karşılaşırsanız lütfen bize " "ulaşın." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Size bir e-posta gönderdik. E-postayı almadıysanız istenmeyen e-posta " "klasörünüzü kontrol ediniz. Eğer birkaç dakika içinde elinize ulaşmaz ise " "bizimle irtibata geçiniz." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Hatalı Anahtar" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Muhtemelen daha önce kullanıldığı için şifre sıfırlama bağlantısı geçersiz. " "Lütfen yeni şifre sıfırlama talebinde " "bulunun." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Şifreniz değiştirildi." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Şifre Belirle" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Şifrenizi giriniz:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Şifresiz giriş yapabilmenizi sağlayan kodu içeren bir e-posta alacaksınız." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "İstek Kodu" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Diğer giriş seçenekleri" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Üye Ol" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Üye Ol" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "Zaten hesabınız var mı? O zaman lütfen %(link)sgiriş yapın%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "Geçiş anahtarı kullanarak giriş yap" #: templates/account/signup_by_passkey.html:8 msgid "Passkey Sign Up" msgstr "Geçiş Anahtarı ile Üye Ol" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "Diğer seçenekler" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Kayıt Kapalı" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Üzgünüz, ancak kayıt şu anda kapalıdır." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Not" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Halihazırda %(user_display)s olarak giriş yapmış durumdasınız." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Uyarı:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Şu anda tanımlı hiçbir e-posta adresiniz yok. Bildirim alabilmek, şifrenizi " "sıfırlayabilmek ve benzeri eylemler için e-posta adresinizi mutlaka " "eklemelisiniz." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "E-posta Adresinizi Doğrulayın" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Size, doğrulama amaçlı bir e-posta gönderdik. Kayıt olma aşamasını " "tamamlamak için bağlantıyı ziyaret ediniz. Eğer doğrulama e-postasını gelen " "kutunuzda göremiyorsanız istenmeyen e-posta klasörünüzü kontrol ediniz. Eğer " "e-posta birkaç dakika içinde tarafınıza ulaşmaz ise bizimle irtibata geçiniz." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Sitenin bu kısmı kim olduğunuzu doğrulamanızı\n" "gerektirmektedir. Bu sebeple, girdiğiniz e-posta adresinize sahip\n" "olduğunuzu doğrulamanızı rica ediyoruz. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Doğrulama için size bir e-posta gönderdik.\n" "Lütfen e-postadaki bağlantıyı ziyaret edin. Eğer e-postayı gelen kutunuzda " "göremiyorsanız istenmeyen e-posta klasörünüzü kontrol edin. Eğer birkaç " "dakika\n" "içinde bu e-postayı almazsanız bize ulaşın." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Not: hala e-posta adresinizi " "değiştirebilirsiniz." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Mesajlar:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menü:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Hesap Bağlantıları" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "İki Faktörlü Kimlik Doğrulama" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Oturumlar" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Hesabınız iki faktörlü kimlik doğrulama ile korunmaktadır. Lütfen bir " "doğrulama kodu giriniz:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "Yeni iki faktörlü kimlik doğrulama kurtarma kodu dizesi oluşturuldu." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Yeni Kurtarma Kodları Oluşturuldu" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Kimlik doğrulama uygulaması etkinleştirildi." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Kimlik Doğrulama Uygulaması Etkinleştirildi" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Kimlik doğrulama uygulaması devre dışı bırakıldı." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Kimlik Doğrulama Uygulaması Devre Dışı Bırakıldı" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Yeni bir güvenlik anahtarı eklendi." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Güvenlik Anahtarı Eklendi" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Bir güvenlik anahtarı kaldırıldı." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Güvenlik Anahtarı Kaldırıldı" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Kimlik Doğrulama Uygulaması" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Kimlik doğrulama uygulaması aracılığı ile kimlik doğrulama etkin." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Bir kimlik doğrulama uygulaması etkin değil." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Devre Dışı Bırak" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Etkinleştir" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Güvenlik Anahtarları" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "%(count)s adet güvenlik anahtarı eklediniz." msgstr[1] "%(count)s adet güvenlik anahtarı eklediniz." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Hiçbir güvenlik anahtarı eklenmedi." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Yönet" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Ekle" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Kurtarma Kodları" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" "%(total_count)s adet kurtarma kodu içerisinden %(unused_count)s sayıda " "kurtarma kodu uygun durumda." msgstr[1] "" "%(total_count)s adet kurtarma kodu içerisinden %(unused_count)s sayıda " "kurtarma kodu uygun durumda." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Tanımlı kurtarma kodu bulunmamakta." #: templates/mfa/index.html:96 msgid "View" msgstr "İncele" #: templates/mfa/index.html:102 msgid "Download" msgstr "İndir" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Oluştur" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Yeni bir kurtarma kodu dizesi oluşturuldu." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Güvenlik anahtarı eklendi." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Güvenlik anahtarı kaldırıldı." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Bir kimlik doğrulama kodu gir:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Hesabınız için yeni bir kurtarma kodu dizesi oluşturmak üzeresiniz." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Bu eylem, halihazırda mevcut olan kodlarınızı geçersiz kılacaktır." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Emin misin?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Kullanılmamış kodlar" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Kodları indir" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Yeni kod oluştur" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Kimlik Doğrulama Uygulaması Etkinleştir" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Hesabınızı iki faktörlü kimlik doğrulama ile korumak adına aşağıdaki QR " "kodunu kimlik doğrulama uygulamanız ile tarayınız. Sonrasında uygulama " "tarafından oluşturulan doğrulama kodunu aşağıdaki kısma giriniz." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Kimlik doğrulama anahtarı" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Bu anahtarı saklayabilir ve kimlik doğrulama uygulamanızı ileriki bir " "zamanda yeniden yüklemek için kullanabilirsiniz." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Kimlik Doğrulama Uygulamasını Devre Dışı Bırak" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Kimlik doğrulama uygulaması tabanlı kimlik doğrulamayı devre dışı bırakmak " "üzeresiniz. Bunu yapmak istediğinizden emin misiniz?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Güvenlik Anahtarı Ekle" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Güvenlik Anahtarı Kaldır" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Bu güvenlik anahtarını kaldırmak istediğinizden emin misiniz?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Kullanım" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Geçiş Anahtarı" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Güvenlik anahtarı" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Bu anahtar, bir geçiş anahtarı olduğunu belirtmiyor." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Belirtilmemiş" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "%(created_at)s tarihinde eklendi" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "En son %(last_used)s tarihinde kullanıldı" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Düzenle" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Güvenlik Anahtarını Düzenle" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Kaydet" #: templates/mfa/webauthn/signup_form.html:7 msgid "Create Passkey" msgstr "Geçiş Anahtarı Oluştur" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" "Hesabınız için geçiş anahtarı oluşturmak üzeresiniz. İleriki zamanlarda ek " "anahtarlar ekleyebileceğiniz gibi anahtarları ayırt etmek adına açıklayıcı " "isimler kullanabilirsiniz." #: templates/mfa/webauthn/signup_form.html:21 msgid "Create" msgstr "Oluştur" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Bu özellik JavaScript gerektirir." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Üçüncü Taraf Giriş Hatası" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "Üçüncü taraf hesabınız ile giriş yapılırken bir hata meydana geldi." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Hesabınıza aşağıdaki üçüncü taraf hesaplar aracılığı ile giriş " "yapabilirsiniz." #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Bu hesap ile bağlantılı hiçbir üçüncü taraf hesap bulunmamakta." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Üçüncü Taraf Hesap ekle" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "%(provider)s üzerinden bir üçüncü taraf hesap, hesabınız ile " "ilişkilendirildi." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Üçüncü Taraf Hesap İlişkilendirildi" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "%(provider)s üzerinden üçüncü taraf bir hesabın, hesabınız ile olan " "bağlantısı kesildi." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Üçüncü Taraf Hesap Bağlantısı Kesildi" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "%(provider)s Bağlantısı Kur" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "%(provider)s üzerinden yeni bir üçüncü taraf hesap bağlantısı kurmak " "üzeresiniz." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "%(provider)s ile Giriş Yap" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "%(provider)s üzerinden bir üçüncü taraf hesap ile giriş yapmak üzeresiniz." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "İlerle" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Giriş İptal Edildi" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Mevcut hesaplarınızdan birisiyle sitemize girişinizi iptal etmeye karar " "verdiniz. Eğer bu yanlışlıkla olduysa, lütfen devam edin: giriş yapın." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Üçüncü taraf hesap bağlantısı kuruldu." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Üçüncü taraf hesap bağlantısı kesildi." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "%(provider_name)s hesabınızı kullanarak %(site_name)s sitesine giriş yapmak " "üzeresiniz.\n" "Son aşama olarak lütfen formu doldurunuz:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Veya üçüncü taraf bir uygulama kullan" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Diğer tüm oturumlardan çıkış yapıldı." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Şu Tarihte Başladı" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP Adresi" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Tarayıcı" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "En son şu tarihte görüldü" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Şu anki" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Diğer Oturumlardan Çıkış Yap" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Kullanıcı Oturumları" #: usersessions/models.py:92 msgid "session key" msgstr "oturum anahtarı" #~ msgid "Account Connection" #~ msgstr "Hesap Bağlantısı" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "Parola en az {0} karakter olmalıdır." #, python-format #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "Bu e-postayı alıyorsunuz çünkü siz veya başka biri kullanıcı hesabınız " #~ "için\n" #~ "bir şifre talebinde bulundu. Ancak,veritabanımızda %(email)s e-posta " #~ "adresi ile ilgili bir kayıt bulunmamaktadır.\n" #~ "\n" #~ "Eğer şifre sıfırlama talebinde bulunmadıysanız bu e-posta güvenle göz " #~ "ardı edilebilir.\n" #~ "\n" #~ "Eğer talep sizden geldiyse, aşağıdaki bağlantıyı kullanarak bir hesap " #~ "oluşturabilirsiniz." #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "Şu e-posta adresleri hesabınızla ilişkilendirildi:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "E-posta Adresi Doğrula" #~ msgid "or" #~ msgstr "ya da" #~ msgid "change password" #~ msgstr "parola değiştir" #~ msgid "OpenID Sign In" #~ msgstr "OpenID Girişi" #~ msgid "This email address is already associated with another account." #~ msgstr "Bu e-post adresi başka bir hesap ile ilişkilendirilmiş." #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "Size bir e-posta gönderdik. Birkaç dakika içerisinde size ulaşmazsa " #~ "lütfen bize ulaşın." #~ msgid "The login and/or password you specified are not correct." #~ msgstr "Girdiğiniz giriş bilgisi ve/veya parola doğru değil." #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "Kullanıcı adları sadece harf, rakam ve @/./+/-/_ içerebilir." #~ msgid "This username is already taken. Please choose another." #~ msgstr "Bu kullanıcı adı alınmış durumda. Lütfen başka bir tane deneyiniz." #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "Giriş Yap" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "%(email)s adresinin %(user_display)s " #~ "kullanıcısına ait olduğunu onayladınız." #~ msgid "Thanks for using our site!" #~ msgstr "Sitemizi kullandığınız için teşekkür ederiz!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "Onay e-postası %(email)s adresine gönderildi." #~ msgid "Delete Password" #~ msgstr "Parola Sil" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "" #~ "Şu anda OpenID ile giriş yaptığınız için dilerseniz parolanızı " #~ "silebilirsiniz." #~ msgid "delete my password" #~ msgstr "parolamı sil" #~ msgid "Password Deleted" #~ msgstr "Parola Silindi" django-allauth-65.0.2/allauth/locale/uk/000077500000000000000000000000001467545753200200305ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/uk/LC_MESSAGES/000077500000000000000000000000001467545753200216155ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/uk/LC_MESSAGES/django.po000066400000000000000000001730561467545753200234330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-04-20 22:11+0200\n" "Last-Translator: Michael Husiev \n" "Language-Team: LANGUAGE \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != " "11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % " "100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || " "(n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Цей обліковий запис наразі неактивний." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Ви не можете видалити свою основну адресу електронної пошти." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Ця адреса електронної пошти вже пов'язана з цим обліковим записом." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Вказана адреса електронної пошти та/або пароль неправильні." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Користувач з цією адресою електронної пошти вже зареєстрований." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Будь ласка, введіть свій поточний пароль." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Неправильний код." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Неправильний пароль." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Недійсний або прострочений ключ." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Токен відновлення пароля недійсний." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Ви не можете додати більше ніж %d адрес електронної пошти." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "Занадто багато невдалих спроб входу. Спробуйте ще раз пізніше." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "" "Ця адреса електронної пошти не призначена для жодного облікового запису" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Ваша основна адреса електронної пошти повинна бути підтверджена." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Ім'я користувача не може бути використане. Будь ласка, виберіть інше ім'я " "користувача." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Вказане ім'я користувача або пароль неправильні." #: account/adapter.py:741 msgid "Use your password" msgstr "Використовуйте свій пароль" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Використовуйте додаток для аутентифікації або код" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Використовуйте ключ безпеки" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Позначте обрані адреси електронної пошти як підтверджені" #: account/apps.py:11 msgid "Accounts" msgstr "Облікові записи" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Вам потрібно вводити один і той самий пароль кожен раз." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Пароль" #: account/forms.py:93 msgid "Remember Me" msgstr "Запам'ятати Мене" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Адреса електронної пошти" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Електронна пошта" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Ім'я користувача" #: account/forms.py:123 msgid "Username or email" msgstr "Ім'я користувача або електронна пошта" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Вхід" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Забули пароль?" #: account/forms.py:299 msgid "Email (again)" msgstr "Електронна пошта (ще раз)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Підтвердження адреси електронної пошти" #: account/forms.py:311 msgid "Email (optional)" msgstr "Електронна пошта (необов'язково)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Ви повинні вводити одну й ту ж електронну пошту кожен раз." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Пароль (ще раз)" #: account/forms.py:554 msgid "Current Password" msgstr "Поточний Пароль" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Новий Пароль" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Новий Пароль (ще раз)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Код" #: account/models.py:26 msgid "user" msgstr "користувач" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "адреса електронної пошти" #: account/models.py:34 msgid "verified" msgstr "підтверджено" #: account/models.py:35 msgid "primary" msgstr "основна" #: account/models.py:41 msgid "email addresses" msgstr "адреси електронної пошти" #: account/models.py:150 msgid "created" msgstr "створено" #: account/models.py:151 msgid "sent" msgstr "відправлено" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "ключ" #: account/models.py:157 msgid "email confirmation" msgstr "підтвердження електронної пошти" #: account/models.py:158 msgid "email confirmations" msgstr "підтвердження електронної пошти" #: headless/apps.py:7 msgid "Headless" msgstr "Без візуального інтерфейсу" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Ви не можете додати адресу електронної пошти до облікового запису, який " "захищений двофакторною аутентифікацією." #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Ви не можете вимкнути двофакторну аутентифікацію." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Ви не можете створити коди відновлення без увімкненої двофакторної " "аутентифікації." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Ви не можете увімкнути двофакторну аутентифікацію, поки не підтвердите свою " "адресу електронної пошти." #: mfa/adapter.py:141 msgid "Master key" msgstr "Головний ключ" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Резервний ключ" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Ключ № {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "Багатофакторна аутентифікація" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Коди для відновлення" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "Аутентифікатор TOTP" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Код аутентифікатора" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Без пароля" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Увімкнення режиму без пароля дозволяє вам увійти, використовуючи лише цей " "ключ, але передбачає додаткові вимоги, такі як біометричні дані або захист " "PIN-кодом." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Обліковий запис вже існує з цією адресою електронної пошти. Будь ласка, " "спочатку увійдіть в цей обліковий запис, а потім підключіть ваш обліковий " "запис %s." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Недійсний токен." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "У вашому обліковому записі не встановлено пароль." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "" "У вашому обліковому записі не підтверджено жодної адреси електронної пошти." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "" "Ви не можете відключити ваш останній обліковий запис стороннього " "постачальника." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "" "Обліковий запис стороннього постачальника вже підключений до іншого " "облікового запису." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Облікові Записи Соціальних Мереж" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "постачальник" #: socialaccount/models.py:52 msgid "provider ID" msgstr "ідентифікатор постачальника" #: socialaccount/models.py:56 msgid "name" msgstr "ім'я" #: socialaccount/models.py:58 msgid "client id" msgstr "ідентифікатор клієнта" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Ідентифікатор додатка або ключ споживача" #: socialaccount/models.py:63 msgid "secret key" msgstr "ключ" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API ключ, клієнтський ключ або ключ споживача" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Ключ" #: socialaccount/models.py:81 msgid "social application" msgstr "додаток соціальної мережі" #: socialaccount/models.py:82 msgid "social applications" msgstr "додатки соціальної мережі" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "останній вхід" #: socialaccount/models.py:120 msgid "date joined" msgstr "дата приєднання" #: socialaccount/models.py:121 msgid "extra data" msgstr "додаткові дані" #: socialaccount/models.py:125 msgid "social account" msgstr "обліковий запис соціальної мережі" #: socialaccount/models.py:126 msgid "social accounts" msgstr "облікові записи соціальних мереж" #: socialaccount/models.py:160 msgid "token" msgstr "токен" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) або токен доступу (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "ключ токена" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) або токен оновлення (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "діє до" #: socialaccount/models.py:174 msgid "social application token" msgstr "токен додатку соціальної мережі" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "токени додатків соціальної мережі" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Недійсні дані профілю" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Увійти" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Скасувати" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "" "Недійсна відповідь при отриманні токена запиту від \"%s\". Відповідь була: " "%s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Недійсна відповідь під час отримання токена доступу від \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "Не збережено токен запиту для \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "Не збережено токен доступу для \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "Немає доступу до приватних ресурсів за \"%s\"." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Недійсна відповідь при отриманні токена запиту від \"%s\"" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Обліковий Запис Неактивний" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Цей обліковий запис неактивний." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Підтвердіть Доступ" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" "Будь ласка, проведіть повторну аутентифікацію для захисту вашого облікового " "запису." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Альтернативні варіанти" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "Підтвердження Електронної Пошти" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "Введіть код з аутентифікаційного додатка:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Ми відправили код на %(email_link)s. Код скоро застаріє, тому будь ласка, " "введіть його найближчим часом." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Підтвердити" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Увійти" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Введіть Код Для Входу." #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Адреси електронної пошти" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Ваш обліковий запис пов'язано з наступними адресами електронної пошти:" #: templates/account/email.html:25 msgid "Verified" msgstr "Підтверджено" #: templates/account/email.html:29 msgid "Unverified" msgstr "Непідтверджено" #: templates/account/email.html:34 msgid "Primary" msgstr "Основний" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Зробити Основним" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Надіслати Повторне Підтвердження" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "Видалити" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Додати Адресу Електронної Пошти" #: templates/account/email.html:70 msgid "Add Email" msgstr "Додати Електронну Пошту" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Ви дійсно хочете видалити обрану адресу електронної пошти?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Ви отримали цей лист, оскільки ви або хтось інший намагались зареєструвати " "обліковий запис за допомогою адреси електронної пошти:\n" "\n" "%(email)s\n" "\n" "Однак вже існує обліковий запис з цією адресою електронної пошти. Якщо ви " "забули про це, будь ласка, скористайтеся процедурою відновлення паролю, щоб " "відновити свій обліковий запис:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Обліковий Запис Вже Існує" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "Привіт від %(site_name)s!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "Дякуємо за використання %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Ви отримуєте цей лист, оскільки була зроблена наступна зміна у вашому " "обліковому записі:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Якщо ви не впізнаєте цю зміну, будь ласка, негайно прийміть відповідні " "заходи безпеки. Зміна у вашому обліковому записі походить з:\n" "\n" "- IP-адреса: %(ip)s\n" "- Браузер: %(user_agent)s\n" "- Дата: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Ваша електронна пошта була змінена з %(from_email)s на %(to_email)s." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Електронна Пошта Змінена" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Ваша електронна пошта підтверджена." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Підтвердження Електронної Пошти" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Ви отримали цей лист, оскільки користувач %(user_display)s вказав вашу " "електронну пошту для реєстрації облікового запису на %(site_domain)s.\n" "\n" "Для підтвердження цього відкрийте %(activate_url)s" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Нижче наведений код для входу. Будь ласка, введіть його у відкритому вікні " "браузера." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Будь Ласка, Підтвердіть Вашу Адресу Електронної Пошти" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" "Адресу електронної пошти %(deleted_email)s було видалено з вашого облікового " "запису." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Електронна Пошта Видалена" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Нижче наведений код для входу. Будь ласка, введіть його у відкритому вікні " "браузера." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "Цей лист можна безпечно ігнорувати, якщо ви не ініціювали цю дію." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Код Для Входу" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Ваш пароль було змінено." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Пароль Змінено" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Ви отримали цей лист, оскільки ви або хтось інший запросив відновлення " "пароля для вашого облікового запису.\n" "\n" "Цей лист можна безпечно ігнорувати, якщо ви не запитували відновлення " "пароля. Клацніть по посиланню нижче, щоб відновити пароль." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Якщо ви забули, ваше ім'я користувача - %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Лист Для Відновлення Пароля" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Ваш пароль було відновленно." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Відновлення Пароля" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Ваш пароль було встановлено." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Встановити Пароль" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Ви отримали цей лист, оскільки ви або хтось інший спробували отримати доступ " "до облікового запису з електронною поштою %(email)s. Проте у нашій базі " "даних немає жодного запису такого облікового запису." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Якщо це були ви, ви можете зареєструватися для облікового запису за " "допомогою посилання нижче." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Невідомий Обліковий Запис" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Адреса Електронної Пошти" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Поточна електронна пошта" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "Зміна на" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "Ваша адреса електронної пошти ще не підтверджена." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "Відмінити Зміну" #: templates/account/email_change.html:49 msgid "Change to" msgstr "Зміна на" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Змінити Електронну Пошту" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Підтвердити Адресу Електронної Пошти" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Будь ласка, підтвердіть, що %(email)s є " "адресоюелектронної пошти для користувача %(user_display)s." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "Не вдалося підтвердити %(email)s, оскільки вона вже підтверджена іншим " "обліковим записом." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Термін дії посилання для підтвердження електронної пошти закінчився або воно " "є недійсним. Будь ласка, відправте новий запит на " "підтвердження електронної пошти." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Якщо ви ще не створили обліковий запис, будь ласка, спочатку " "%(link)sзареєструйтесь%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "Увійти за допомогою пароль-ключа" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Надішліть мені код для входу" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Вийти" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Ви впевнені, що хочете вийти?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "" "Ви не можете видалити свою основну адресу електронної пошти (%(email)s)." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Лист-підтвердження надіслано на %(email)s." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "Ви підтвердили %(email)s." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "Видалено адресу електронної пошти %(email)s." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "Успішно увійшли як %(name)s." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Ви вийшли." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Код для входу було надіслано на %(email)s." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Пароль успішно змінено." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Пароль успішно встановлено." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Основна адреса електронної пошти встановлена." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Змінити Пароль" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Забули Пароль?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Забули пароль? Введіть свою адресу електронної пошти нижче, і ми надішлемо " "вам листа з інструкціями для його відновлення." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Відновити Мій Пароль" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Будь ласка, зв'яжіться з нами, якщо у вас виникли проблеми зі відновлення " "пароля." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Ми відправили вам електронного листа. Якщо ви його не отримали, перевірте " "папку «Спам». В іншому випадку, зверніться до нас, якщо ви не отримаєте його " "протягом кількох хвилин." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Недійсний Токен" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Посилання для відновлення пароля недійсне, можливо, воно вже було " "використане. Будь ласка, запросіть нове " "відновлення пароля." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Ваш пароль було змінено." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Встановити Пароль" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Введіть ваш пароль:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Ви отримаєте електронного листа з особливим кодом для входу без пароля." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Запросити Код" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Інші варіанти входу" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Реєстрація" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Зареєструватись" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "Вже маєте обліковий запис? Тоді будь ласка, %(link)sувійти%(end_link)s." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "Увійти за допомогою пароль-ключа" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Зареєструватись" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Інші варіанти входу" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Реєстрація Закрита" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Вибачте, але реєстрація наразі закрита." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Примітка" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Ви вже увійшли як %(user_display)s." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Попередження:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "На даний момент у вас немає встановленої жодної адреси електронної пошти. " "Рекомендується додати адресу електронної пошти для отримання сповіщень, " "відновлення паролю та інших операцій." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Підтвердіть Вашу Адресу Електронної Пошти" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Ми відправили вам лист для підтвердження. Слідуйте по посиланню, щоб " "завершити процес реєстрації. Якщо ви не знайшли листа в основній скринці, " "перевірте папку «Спам». Будь ласка, зв'яжіться з нами, якщо ви не отримаєте " "листа з підтвердженням протягом кількох хвилин." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Ця частина сайту вимагає підтвердження того, що\n" "ви той, за кого себе видаєте. З цією метою ми потребуємо\n" "підтвердити власність вашої адреси електронної пошти. " #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Ми відправили вам лист для\n" "підтвердження. Будь ласка, перейдіть за посиланням у цьому листі. Якщо ви не " "знайшли листа з підтвердженням у головній скринці, перевірте папку «Спам». " "Інакше\n" "зв'яжіться з нами, якщо ви не отримаєте його протягом кількох хвилин." #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Примітка: ви все ще можете змінити свою адресу електронної пошти." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Повідомлення:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Меню:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Підключені Облікові Записи" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Двофакторна аутентифікація" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Сесії" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Ваш обліковий запис захищений двофакторною аутентифікацією. Будь ласка, " "введіть код автентифікатора:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "Згенеровано новий набір кодів для відновлення двофакторної аутентифікації." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Створено Нові Коди Для Відновлення Доступу" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Аутентифікаційний додаток увімкнено." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Аутентифікаційний Додаток Увімкнено" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Аутентифікаційний додаток вимкнуто." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Аутентифікаційний Додаток Вимкнуто" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Додано новий ключ безпеки." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Додано Ключ Безпеки" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Ключ безпеки було видалено." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Ключ Безпеки Видалено" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Додаток Для Аутентифікації" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Аутентифікація за допомогою додатка для аутентифікації увімкнена." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Додаток для аутентифікації не увімкнений." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Вимкнути" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Увімкнути" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Ключі Безпеки" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Ви додали %(count)s захисний ключ." msgstr[1] "Ви додали %(count)s захисних ключів." msgstr[2] "Ви додали %(count)s захисних ключів." msgstr[3] "Ви додали %(count)s захисних ключів." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Не було додано жодних ключів безпеки." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Керувати" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Додати" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Коди Для Відновлення" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "Доступно %(unused_count)s з %(total_count)s кодів відновлення." msgstr[1] "Доступно %(unused_count)s з %(total_count)s кодів відновлення." msgstr[2] "Доступно %(unused_count)s з %(total_count)s кодів відновлення." msgstr[3] "Доступно %(unused_count)s з %(total_count)s кодів відновлення." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Коди для відновлення не налаштовано." #: templates/mfa/index.html:96 msgid "View" msgstr "Перегляд" #: templates/mfa/index.html:102 msgid "Download" msgstr "Завантажити" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Згенерувати" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Згенеровано новий набір кодів для відновлення." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Додано ключ безпеки." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Ключ безпеки видалено." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Введіть код з аутентифікаційного додатка:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" "Ви збираєтесь згенерувати новий набір кодів для відновлення вашого " "облікового запису." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Ця дія зробить недійсними ваші поточні коди." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Ви впевнені?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Не використані коди" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Завантажити коди" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Згенерувати нові коди" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Увімкнути Додаток Для Аутентифікації" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Для захисту вашого облікового запису двофакторною аутентифікацією " "відскануйте QR-код нижче за допомогою вашого додатка для аутентифікації. " "Потім введіть згенерований додатком код підтвердження нижче." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Ключ аутентифікатора" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Ви можете зберегти цей ключ і використовувати його для перевстановлення " "вашого додатка для аутентифікації в майбутньому." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Вимкнути Додаток Для Аутентифікації" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Ви збираєтесь вимкнути аутентифікацію на основі додатку для аутентифікації. " "Ви впевнені?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Додати Ключ Безпеки" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Видалити Ключ Безпеки" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Ви впевнені, що хочете видалити цей ключ безпеки?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Використання" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "пароль-ключ" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Ключ безпеки" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Цей ключ не вказує, чи є він пароль-ключем." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Невизначений" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "Додано %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "Останнє використання %(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "Редагувати" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Редагувати Ключ Безпеки" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Зберегти" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "пароль-ключ" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "створено" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Ця функція потребує JavaScript." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Невдалий Вхід Через Сторонній Сервіс" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Під час спроби входу через ваш обліковий запис стороннього сервісу сталася " "помилка." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Ви можете увійти до свого облікового запису, використовуючи будь-який з " "наступних облікових записів сторонніх сервісів:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "" "Наразі до цього облікового запису не підключено жодних облікових записів " "сторонніх сервісів." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Додати Обліковий Запис Стороннього Сервісу" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "Обліковий запис від %(provider)s було підключено до вашого облікового запису." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Обліковий Запис Стороннього Сервісу Підключено" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "Обліковий запис від %(provider)s було відключено від вашого облікового " "запису." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Обліковий Запис Стороннього Сервісу Відключено" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "Підключити %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" "Ви збираєтеся підключити новий обліковий запис стороннього сервісу " "%(provider)s." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "Увійти через %(provider)s" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Ви збираєтеся увійти, використовуючи обліковий запис стороннього сервісу " "%(provider)s." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Продовжити" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Вхід Скасовано" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Ви вирішили скасувати вхід на наш сайт, використовуючи один із ваших " "існуючих облікових записів. Якщо це була помилка, будь ласка, перейдіть до " "входу." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Обліковий запис стороннього сервісу було підключено." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Обліковий запис стороннього сервісу було відключено." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Ви збираєтеся увійти за допомогою облікового запису %(provider_name)s на\n" " сайт %(site_name)s. Як завершальний крок, будь ласка, заповніть наступну " "форму:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Або скористайтеся стороннім сервісом" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Усі інші сеанси завершено." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Розпочато о" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP Адреса" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Браузер" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Останній вхід о" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Поточний" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Вийти З Інших Сеансів" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Сеанси Користувача" #: usersessions/models.py:92 msgid "session key" msgstr "ключ сеансу" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "Підключені Облікові Записи" django-allauth-65.0.2/allauth/locale/uz/000077500000000000000000000000001467545753200200475ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/uz/LC_MESSAGES/000077500000000000000000000000001467545753200216345ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/uz/LC_MESSAGES/django.po000066400000000000000000001431651467545753200234500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Hojiakbar Barotov barotovhojiakbar.me@gmail.com, 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Hojiakbar Barotov barotovhojiakbar.me@gmail.com\n" "Language-Team: LANGUAGE \n" "Language: Uzbek\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "Bu akkaunt hozirda faol emas." #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "Siz asosiy email manzilingizni olib tashlay olmaysiz." #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "Bu email manzili allaqachon ushbu akkaunt bilan bog'langan." #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "Siz ko'rsatgan email manzili va/yoki parol noto'g'ri." #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "Foydalanuvchi allaqachon ushbu email manzili bilan ro'yxatdan o'tgan." #: account/adapter.py:62 msgid "Please type your current password." msgstr "Iltimos, joriy parolingizni kiriting." #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "Noto'g'ri kod." #: account/adapter.py:64 msgid "Incorrect password." msgstr "Noto'g'ri parol." #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "Yaroqsiz yoki muddati o'tgan kalit." #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "Parolni tiklash tokeni yaroqsiz." #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "Siz %d dan ortiq email manzilini qo‘sha olmaysiz." #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "" "Kirish uchun juda koʻp muvaffaqiyatsiz urinishlar. Keyinroq qayta urinib " "ko'ring." #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "Email manzili hech qanday foydalanuvchi akkauntiga ulanmagan" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "Asosiy email manzilingiz tasdiqlanishi kerak." #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "" "Foydalanuvchi nomidan foydalanib bo'lmaydi. Iltimos, boshqa foydalanuvchi " "nomidan foydalaning." #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "Siz ko'rsatgan foydalanuvchi nomi va/yoki paroli noto'g'ri." #: account/adapter.py:741 msgid "Use your password" msgstr "Parolingizdan foydalanish" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "Autentifikatsiya ilovasi yoki kodidan foydalanish" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "Xavfsizlik kalitidan foydalanish" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "Tanlangan email manzillarini tasdiqlangan deb belgilash" #: account/apps.py:11 msgid "Accounts" msgstr "Akkauntlar" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "Har safar bir xil parolni kiritishingiz kerak." #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "Parol" #: account/forms.py:93 msgid "Remember Me" msgstr "Meni Eslab Qolmoq" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Email manzili" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Email" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "Foydalanuvchi nomi" #: account/forms.py:123 msgid "Username or email" msgstr "Foydalanuvchi nomi yoki email" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "Kirish" #: account/forms.py:137 msgid "Forgot your password?" msgstr "Parolingiz esdan chiqdimi?" #: account/forms.py:299 msgid "Email (again)" msgstr "Email (yana)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Email manzilini tasdiqlash" #: account/forms.py:311 msgid "Email (optional)" msgstr "Email (ixtiyoriy)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "Har safar bir xil email manzilini yozishingiz kerak." #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "Parol (yana)" #: account/forms.py:554 msgid "Current Password" msgstr "Joriy Parol" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "Yangi Parol" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "Yangi Parol (yana)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "Kod" #: account/models.py:26 msgid "user" msgstr "foydalanuvchi" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "email manzili" #: account/models.py:34 msgid "verified" msgstr "tasdiqlangan" #: account/models.py:35 msgid "primary" msgstr "asosiy" #: account/models.py:41 msgid "email addresses" msgstr "email manzillari" #: account/models.py:150 msgid "created" msgstr "yaratilgan" #: account/models.py:151 msgid "sent" msgstr "jo'natilgan" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "kalit" #: account/models.py:157 msgid "email confirmation" msgstr "email orqali tasdiqlash" #: account/models.py:158 msgid "email confirmations" msgstr "email orqali tasdiqlash" #: headless/apps.py:7 msgid "Headless" msgstr "Headless" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "" "Siz ikki-bosqichli autentifikatsiya bilan himoyalangan akkauntga email " "manzilini qo'sha olmaysiz" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "Ikki-bosqichli autentifikatsiyani o'chirib bo'lmaydi." #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "" "Siz ikki-bosqichli autentifikatsiyasiz tiklash kodlarini yarata olmaysiz." #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "" "Siz email manzilingizni tasdiqlamaguningizcha ikki-bosqichli " "autentifikatsiyani faollashtira olmaysiz." #: mfa/adapter.py:141 msgid "Master key" msgstr "Asosiy kalit" #: mfa/adapter.py:143 msgid "Backup key" msgstr "Zaxira kalit" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "Kalit No. {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "Ko'p faktorli autentifikatsiya" #: mfa/models.py:24 msgid "Recovery codes" msgstr "Qayta tiklash kodlari" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP Authenticator" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "Autentifikatsiya kodi" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "Parolsiz" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "Parolsiz operatsiyani yoqish sizga faqat shu kalit yordamida tizimga kirish " "imkonini beradi, lekin biometrik yoki PIN-kod himoyasi kabi qo'shimcha " "talablarni qo'yadi." #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "Ushbu email manzili bilan akkaunt allaqachon mavjud. Iltimos, avval o'sha " "akkauntga kiring keyin %s akkauntingizni ulang." #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "Token yaroqsiz." #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "Akkauntingizda parol sozlanmagan." #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "Akkauntingizda tasdiqlangan email manzili yo'q." #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "Oxirgi qolgan uchinchi tomon akkauntingizni oʻchira olmaysiz." #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "Uchinchi tomon akkaunti allaqachon boshqa akkauntga ulangan." #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "Ijtimoiy Akkauntlar" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "provayder" #: socialaccount/models.py:52 msgid "provider ID" msgstr "provayder ID" #: socialaccount/models.py:56 msgid "name" msgstr "nom" #: socialaccount/models.py:58 msgid "client id" msgstr "mijoz identifikatori" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "Ilova identifikatori yoki iste'molchi kaliti" #: socialaccount/models.py:63 msgid "secret key" msgstr "maxfiy kalit" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API kaliti, mijoz kaliti yoki iste'molchi kaliti" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "Kalit" #: socialaccount/models.py:81 msgid "social application" msgstr "ijtimoiy ilova" #: socialaccount/models.py:82 msgid "social applications" msgstr "ijtimoiy ilovalar" #: socialaccount/models.py:117 msgid "uid" msgstr "uid" #: socialaccount/models.py:119 msgid "last login" msgstr "so'nggi kirish" #: socialaccount/models.py:120 msgid "date joined" msgstr "qo'shilgan sana" #: socialaccount/models.py:121 msgid "extra data" msgstr "qo'shimcha ma'lumotlar" #: socialaccount/models.py:125 msgid "social account" msgstr "ijtimoiy akkaunt" #: socialaccount/models.py:126 msgid "social accounts" msgstr "ijtimoiy akkauntlar" #: socialaccount/models.py:160 msgid "token" msgstr "token" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) yoki kirish tokeni (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "token kaliti" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) yoki yangilash tokeni (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "da tugaydi" #: socialaccount/models.py:174 msgid "social application token" msgstr "ijtimoiy tarmoq tokeni" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "ijtimoiy tarmoq tokenlari" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "Profil maʼlumotlari yaroqsiz" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "Kirish" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "Bekor qilish" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "\"%s\"dan soʻrov tokenini olishda yaroqsiz javob. Olingan javob: %s." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "\"%s\"dan kirish tokenini olishda yaroqsiz javob." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "\"%s\" uchun soʻrov tokeni saqlanmagan." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "\"%s\" uchun kirish tokeni saqlanmagan." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "\"%s\" shaxsiy ma'lumotlariga kirish imkoni yo'q." #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "\"%s\"dan soʻrov tokenini olishda yaroqsiz javob." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "Nofaol Akkaunt" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "Bu akkaunt faol emas." #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "Kirishni Tasdiqlash" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "Akkauntingizni himoya qilish uchun qayta autentifikatsiya qiling." #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "Muqobil variantlar" #: templates/account/confirm_email_verification_code.html:5 msgid "Email Verification" msgstr "Emailni Tasdiqlash" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "Email Tasdiqlash Kodini Kiritish" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" "Biz %(email_link)s manziliga kod yubordik. Kodning amal qilish muddati tez " "orada tugaydi, iltimos tez orada kodni kiriting." #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "Tasdiqlash" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "Kirish" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "Kirish Kodini Kiritish" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Email Manzillari" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "Quyidagi email manzillari akkauntingiz bilan bog'langan:" #: templates/account/email.html:25 msgid "Verified" msgstr "Tasdiqlangan" #: templates/account/email.html:29 msgid "Unverified" msgstr "Tasdiqlanmagan" #: templates/account/email.html:34 msgid "Primary" msgstr "Asosiy" #: templates/account/email.html:44 msgid "Make Primary" msgstr "Asosiy Sifatida O'rnatish" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "Tekshirishni Qayta Yuborish" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "O'chirish" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "Email Manzili Qo'shish" #: templates/account/email.html:70 msgid "Add Email" msgstr "Email Qo'shish" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "Haqiqatan ham tanlangan email manzilini o'chirib tashlamoqchimisiz?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "Siz ushbu xatni siz yoki boshqa birov\n" "%(email)s email manzilidan foydalanib akkaunt yaratishga harakat qilgani " "uchun oldingiz.\n" "Biroq, bu email manzilidan foydalanadigan hisob allaqachon mavjud.\n" "Bu haqda unutgan bo'lsangiz, hisobingizni tiklash uchun parolni tiklash " "protsedurasidan foydalaning:\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "Akkaunt Allaqachon Mavjud" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "%(site_name)s dan salom!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "%(site_name)s dan foydalanganingiz uchun tashakkur!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" "Sizga quyidagi akkauntga o‘zgartirish kiritilgani uchun bu xatni olmoqdasiz" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "Agar siz bu oʻzgarishdan bexabar bo'lsangiz, darhol tegishli xavfsizlik " "choralarini koʻring. Hisobingizga kiritilgan oʻzgarish:\n" "\n" "- IP manzil: %(ip)s\n" "- Brauzer: %(user_agent)s\n" "- Sana: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "Sizning emailingiz %(from_email)s dan %(to_email)s ga o‘zgartirildi." #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Email O'zgartirildi" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "Emailngiz tasdiqlandi." #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Emailni Tasdiqlash" #: templates/account/email/email_confirmation_message.txt:5 #, python-format msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "Siz bu xatni olmoqdasiz, chunki %(user_display)s foydalanuvchisi " "%(site_domain)s saytida hisob qaydnomasini ro‘yxatdan o‘tkazish uchun email " "manzilingizni bergan." #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" "Emailngizni tasdiqlash kodi quyida keltirilgan. Iltimos, uni ochiq brauzer " "oynasida kiriting." #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "Bu toʻgʻriligini tasdiqlash uchun %(activate_url)s ga oʻting" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "Iltimos, Email Manzilingizni Tasdiqlang" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "%(deleted_email)s email manzili akkauntingizdan olib tashlandi." #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Email Olib Tashlandi" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" "Kirish kodingiz quyida keltirilgan. Iltimos, uni ochiq brauzer oynasida " "kiriting." #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" "Agar siz ushbu harakatni boshlamagan bo'lsangiz, bu xatni e'tiborsiz " "qoldirish mumkin." #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "Kirish Kodi" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "Parolingiz o'zgartirildi." #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "Parol O'zgartirildi" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "Siz yoki boshqa birov foydalanuvchi akkauntingiz uchun parolni tiklashni " "soʻragani uchun bu xatni olmoqdasiz.\n" "Agar siz parolni tiklashni so'ramagan bo'lsangiz, buni e'tiborsiz " "qoldirishingiz mumkin. Parolni tiklash uchun quyidagi havolani bosing." #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "Agar unutgan bo'lsangiz, sizning foydalanuvchi nomingiz %(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "Parolni Tiklash Emaili" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "Parolingiz qayta tiklandi." #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "Parolni Tiklash" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "Parolingiz oʻrnatildi." #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "Parol O'rnatildi" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "Siz yoki boshqa birov %(email)s emaili bilan kirishga harakat qilgani uchun " "ushbu xatni oldingiz Biroq, bizning ma'lumotlar ba'zasida bunday akkaunt " "yo'q." #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" "Agar bu siz bo'lsangiz, quyidagi havola orqali akkaunt yaratishingiz mumkin." #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "Noma'lum Akkaunt" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Email Manzili" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "Joriy email" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "-ga o'zgartirilyapti" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "email manzilingiz hali tasdiqlanishi kutilmoqda." #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "O'zgartirishni Bekor Qilish" #: templates/account/email_change.html:49 msgid "Change to" msgstr "-ga o'zgartirmoq" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "Emailni o'zgartirmoq" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "Email Manzilini Tasdiqlash" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "Iltimos, %(email)s email manzili " "%(user_display)s foydalanuvchisi uchun email ekanligini tasdiqlang." #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "" "%(email)s ni tasdiqlab bo‘lmadi, chunki u allaqachon boshqa akkaunt " "tomonidan tasdiqlangan." #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "Ushbu emailni tasdiqlash havolasi muddati tugagan yoki yaroqsiz. Iltimos, yangi email orqali tasdiqlash so'rovini yuboring." #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "" "Agar siz hali akkaunt yaratmagan bo'lsangiz, iltimos, birinchi " "%(link)sakkaunt yarating%(end_link)s." #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "O'tish kaliti bilan tizimga kirish" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "Menga kirish kodini yuboring" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "Chiqish" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "Haqiqatan ham tizimdan chiqmoqchimisiz?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "Siz asosiy email manzilingizni (%(email)s) olib tashlay olmaysiz." #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "Tasdiqlash xati %(email)s manziliga yuborildi." #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "%(email)s ni tasdiqladingiz." #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "%(email)s email manzili olib tashlandi." #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "%(name)s sifatida muvaffaqiyatli kirildi." #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "Tizimdan chiqdingiz." #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "Kirish kodi %(email)s manziliga yuborildi." #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "Parol muvaffaqiyatli almashtirildi." #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "Parol muvaffaqiyatli oʻrnatildi." #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "Asosiy email manzili oʻrnatildi." #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "Parolni O'zgartirmoq" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "Parolni Unutidingizmi?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "Parolni unutdingizmi? Quyida email manzilingizni kiriting, biz sizga uni " "qayta o'rnatishga ruxsat beruvchi emailni yuboramiz." #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "Parolimni Tiklamoq" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "" "Agar parolingizni qayta tiklashda muammoga duch kelsangiz, biz bilan " "bog'laning." #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "Biz sizga email xabarini yubordik. Agar uni olmagan bo'lsangiz, iltimos, " "spam jildini tekshiring. Aks holda, agar siz uni bir necha daqiqada olmagan " "bo'lsangiz, biz bilan bog'laning." #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Yaroqsiz Token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "Parolni tiklash havolasi yaroqsiz, ehtimol u allaqachon ishlatilgan. " "Iltimos, yangi parolni tiklashni so'rang." #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "Parolingiz o'zgartirildi." #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "Parol O'rnatish" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "Parolingizni kirgizing" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" "Siz parolsiz kirish uchun maxsus kodni o'z ichiga olgan email xabarini " "olasiz." #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "Kod So'rash" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "Boshqa kirish variantlari" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "Ro'yxatdan O'tish" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "Ro'yxatdan O'tish" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "" "Allaqachon akkauntingiz bormi? Unda akkauntingizga " "%(link)skiring%(end_link)s." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "O'tish kaliti bilan tizimga kirish" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "Ro'yxatdan O'tish" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "Boshqa kirish variantlari" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "Ro'yxatdan O'tish Yopiq" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "Kechirasiz, lekin roʻyxatdan oʻtish hozirda yopiq." #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "Eslatma" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "Siz allaqachon %(user_display)s sifatida tizimga kirgansiz." #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "Ogohlantirish:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "Sizda hozirda hech qanday email manzili oʻrnatilmagan. Haqiqatan ham " "bildirishnomalarni qabul qilish, parolni tiklash va h.k. uchun email manzil " "qoʻshishingiz kerak." #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "Email Manzilingizni Tasdiqlash" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "Tasdiqlash uchun sizga xat yubordik. Roʻyxatdan oʻtish jarayonini yakunlash " "uchun taqdim etilgan havolaga oʻting. Agar tasdiqlash xatini asosiy pochta " "qutingizda koʻrmasangiz, spam jildini tekshiring. Agar bir necha daqiqa " "ichida tasdiqlash xatini olmagan boʻlsangiz, biz bilan bogʻlaning." #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "Saytning ushbu qismi bizdan\n" " siz o'zingizni da'vo qilayotgan shaxs ekanligingizni tasdiqlashimizni talab " "qiladi. Buning uchun\n" " email manzilingizga egaligingizni tasdiqlashingizni talab qilamiz." #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "Tasdiqlash uchun\n" " sizga xat yubordik. Iltimos, ushbu xat ichidagi havolani bosing. Agar " "tasdiqlash xatini asosiy pochta qutingizda koʻrmasangiz, spam jildini " "tekshiring. Aks holda bir necha daqiqa ichida uniqabul qilmasangiz,\n" " biz bilan bogʻlaning. " #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "Eslatma: siz hali ham email " "manzilingizni o‘zgartirishingiz mumkin." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "Xabarlar:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "Menyu:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "Ulangan Akkauntlar" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "Ikki-bosqichli Autentifikatsiya" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "Seanslar" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" "Akkauntingiz ikki-bosqichli autentifikatsiya bilan himoyalangan. Iltimos, " "autentifikatsiya kodini kiriting:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" "Ikki-bosqichli autentifikatsiyani tiklash kodlarining yangi to'plami " "yaratildi." #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "Yangi Tiklash Kodlari Yaratildi" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "Autentifikatsiya ilovasi faollashtirildi." #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "Autentifikatsiya Ilovasi Faollashtirildi" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "Authenticator ilovasi faolsizlantirildi." #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "Authenticator Ilovasi Faolsizlantirildi" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "Yangi elektron kalit qo‘shildi." #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "Elektron Kalit Qo'shildi" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "Elektron kalit olib tashlandi." #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "Elektron Kalit Olib Tashlandi" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "Autentifikatsiya Ilovasi" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "Autentifikatsiya ilovasi orqali autentifikatsiya faol." #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "Autentifikatsiya ilovasi faol emas." #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "Faolsizlantirish" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "Faollashtirish" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "Xavfsizlik Kalitlari" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "Siz %(count)sta elektron kalit qo‘shdingiz." msgstr[1] "Siz %(count)sta elektron kalit qo‘shdingiz." #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "Hech qanday xavfsizlik kalitlari qo'shilmadi." #: templates/mfa/index.html:62 msgid "Manage" msgstr "Boshqarish" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "Qo'shish" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "Tiklash Kodlari" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "%(unused_count)s/%(total_count)s tiklash kodlari mavjud." msgstr[1] "%(unused_count)s/%(total_count)s tiklash kodlari mavjud." #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "Qayta tiklash kodlari sozlanmagan." #: templates/mfa/index.html:96 msgid "View" msgstr "Ko‘rish" #: templates/mfa/index.html:102 msgid "Download" msgstr "Yuklab Olish" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "Yaratish" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "Qayta tiklash kodlarining yangi to'plami yaratildi." #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "Elektron kalit qo'shildi." #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "Elektron kalit olib tashlandi." #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "Autentifikatsiya kodini kiriting:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "Akkauntingiz uchun yangi tiklash kodlari toʻplamini yaratasiz." #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "Ushbu harakat mavjud kodlaringizni bekor qiladi." #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "Ishonchingiz komilmi?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "Ishlatilmagan kodlar" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "Kodlarni yuklab olish" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "Yangi kodlarni hosil qilish" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "Autentifikatsiya Ilovasini Faollashtirish" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "Akkauntingizni ikki-bosqichli autentifikatsiya bilan himoya qilish uchun " "autentifikatsiya ilovasi yordamida quyidagi QR kodni skanerlang. Keyin ilova " "tomonidan yaratilgan tasdiqlash kodini kiriting." #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "Autentifikatsiya kaliti" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" "Siz ushbu kalitni saqlashingiz va undan keyinroq autentifikatsiya " "ilovangizni qayta oʻrnatish uchun foydalanishingiz mumkin." #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "Autentifikatsiya Ilovasini Faolsizlantirish" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" "Siz autentifikatsiya qiluvchi ilovaga asoslangan autentifikatsiyani o'chirib " "qo'ymoqchisiz. Ishonchingiz komilmi?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "Elektron Kalit Qo'shish" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "Elektron Kalitni Olib Tashlash" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "Haqiqatan ham bu elektron kalitni olib tashlamoqchimisiz?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "Qo'llanilish" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "O'tish kaliti" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "Xavfsizlik kaliti" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "Bu kalit uning o'tish kaliti yoki yo'qligini bildirmaydi." #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "Aniqlanmagan" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "%(created_at)s da qoʻshilgan" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "%(last_used)s da oxirgi marta ishlatilgan" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "O'zgartirish" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "Elektron Kalitni O'zgartirish" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "Saqlash" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "O'tish kaliti" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "yaratilgan" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "Bu funksiya JavaScript-ni talab qiladi." #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "Uchinchi Tomon Tizimga Kirishda Xato" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "" "Uchinchi tomon akkauntingiz orqali kirishga urinishda xatolik yuz berdi." #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "" "Siz quyidagi uchinchi tomon akkauntlaridan foydalanib akkauntingizga " "kirishingiz mumkin:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "Sizda hozirda ushbu akkauntga ulangan uchinchi tomon akkauntlari yo'q." #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "Uchinchi Tomon Aakkauntini Qo'shish" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" "%(provider)s kompaniyasining uchinchi tomon akkaunti sizning akkauntingizga " "ulandi." #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "Uchinchi Tomon Akkaunti Ulandi" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" "%(provider)s kompaniyasining uchinchi tomon akkaunti sizning akkauntingizdan " "uzildi." #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "Uchinchi Tomon Akkaunti Uzildi" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "%(provider)sni Ulash" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "Siz %(provider)s dan yangi uchinchi tomon akkauntini ulamoqchisiz." #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "%(provider)s Orqali Kirish" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" "Siz %(provider)s dan uchinchi tomon akkaunti orqali tizimga kirmoqchisiz." #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "Davom Etish" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "Kirish Bekor Qilindi" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "Siz mavjud akkauntlaringizdan biri yordamida saytimizga kirishni bekor " "qilishga qaror qildingiz. Agar bu xato boʻlsa, kirishga oʻting." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "Uchinchi tomon akkaunti ulandi." #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "Uchinchi tomon akkaunti uzildi." #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "Siz %(site_name)s saytiga kirish uchun\n" "%(provider_name)s akkauntingizdan foydalanmoqchisiz. Yakuniy qadam sifatida " "quyidagi formani to‘ldiring:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "Yoki uchinchi tomondan foydalaning" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "Boshqa barcha seanslardan chiqildi." #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "Boshlangan" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP Manzil" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "Brauzer" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "Oxirgi marta ko'rilgan" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "Hozirgi" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "Boshqa Seanslardan Chiqish" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "Foydalanuvchi Seanslari" #: usersessions/models.py:92 msgid "session key" msgstr "seans kaliti" #~ msgid "Account Connection" #~ msgstr "Akkauntga Bog'lanish" django-allauth-65.0.2/allauth/locale/zh_Hans/000077500000000000000000000000001467545753200210035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/zh_Hans/LC_MESSAGES/000077500000000000000000000000001467545753200225705ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/zh_Hans/LC_MESSAGES/django.po000066400000000000000000001376251467545753200244100ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-07-23 14:40+0000\n" "Last-Translator: Zhuo Cheng \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.7-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "此账号当前未激活。" #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "您不能删除您的主Email地址 (%(email)s)。" #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "此Email地址已关联到这个账号。" #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "您提供的Email地址或密码不正确。" #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "此email地址已被其他用户注册。" #: account/adapter.py:62 msgid "Please type your current password." msgstr "请输入您的当前密码。" #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "错误代码。" #: account/adapter.py:64 msgid "Incorrect password." msgstr "无效密码。" #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "令牌无效或过期。" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "您重置密码的token是无效的。" #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "您不能添加超过%d个Email地址。" #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "登录失败次数过多,请稍后重试。" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "此email地址未分配给任何用户账号" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "您的主Email地址必须被验证。" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "此用户名不能使用,请改用其他用户名。" #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "您提供的用户名或密码不正确。" #: account/adapter.py:741 msgid "Use your password" msgstr "使用您的密码" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "请使用认证APP或代码" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 msgid "Use a security key" msgstr "使用安全密钥" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "将选定的email地址标注为已验证" #: account/apps.py:11 msgid "Accounts" msgstr "账户" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "每次输入的密码必须相同。" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "密码" #: account/forms.py:93 msgid "Remember Me" msgstr "记住我" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "Email地址" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "Email" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "用户名" #: account/forms.py:123 msgid "Username or email" msgstr "用户名或email" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "登录" #: account/forms.py:137 msgid "Forgot your password?" msgstr "忘记密码?" #: account/forms.py:299 msgid "Email (again)" msgstr "Email (再次输入)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "Email地址确认" #: account/forms.py:311 msgid "Email (optional)" msgstr "Email (选填项)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "每次输入的Email必须相同。" #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "密码(重复)" #: account/forms.py:554 msgid "Current Password" msgstr "当前密码" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "新密码" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "新密码(重复)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "代码" #: account/models.py:26 msgid "user" msgstr "用户" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "Email地址" #: account/models.py:34 msgid "verified" msgstr "已验证" #: account/models.py:35 msgid "primary" msgstr "首选Email" #: account/models.py:41 msgid "email addresses" msgstr "Email地址" #: account/models.py:150 msgid "created" msgstr "已建立" #: account/models.py:151 msgid "sent" msgstr "已发送" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "密钥" #: account/models.py:157 msgid "email confirmation" msgstr "Email确认" #: account/models.py:158 msgid "email confirmations" msgstr "Email确认" #: headless/apps.py:7 msgid "Headless" msgstr "无头" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "您不能在开启了两步验证的账户中添加Email地址。" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "您不能停用两步验证。" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "未启用两步验证,您无法生成恢复代码。" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "在验证您的Email地址之前,您不能激活两步验证。" #: mfa/adapter.py:141 msgid "Master key" msgstr "主密钥" #: mfa/adapter.py:143 msgid "Backup key" msgstr "备份密钥" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "密钥 {number}" #: mfa/apps.py:9 msgid "MFA" msgstr "多因素认证" #: mfa/models.py:24 msgid "Recovery codes" msgstr "恢复代码" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP 认证器" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "认证器代码" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "无密码" #: mfa/webauthn/forms.py:59 msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "启用无密码操作允许您仅使用此密钥登录,但会提出其他要求,例如生物特征或PIN保" "护。" #: socialaccount/adapter.py:36 #, python-format msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "已有一个账号与此Email地址关联。请先登录该账号,然后连接您的 %s 账号。" #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "令牌无效。" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "您的账号未设置密码。" #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "您的账号下无任何验证过的email地址。" #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "您不能断开您剩下的唯一的第三方账号。" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 msgid "The third-party account is already connected to a different account." msgstr "该第三方账号已连接到另一个账户。" #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "社交账户" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "提供者" #: socialaccount/models.py:52 msgid "provider ID" msgstr "提供者ID" #: socialaccount/models.py:56 msgid "name" msgstr "名字" #: socialaccount/models.py:58 msgid "client id" msgstr "客户端ID" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "应用ID或消费者密钥" #: socialaccount/models.py:63 msgid "secret key" msgstr "密钥" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API密钥、客户端密钥或消费者密钥" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "密钥" #: socialaccount/models.py:81 msgid "social application" msgstr "社交应用" #: socialaccount/models.py:82 msgid "social applications" msgstr "社交应用程序" #: socialaccount/models.py:117 msgid "uid" msgstr "用户ID" #: socialaccount/models.py:119 msgid "last login" msgstr "最后一次登录" #: socialaccount/models.py:120 msgid "date joined" msgstr "加入日期" #: socialaccount/models.py:121 msgid "extra data" msgstr "额外数据" #: socialaccount/models.py:125 msgid "social account" msgstr "社交账户" #: socialaccount/models.py:126 msgid "social accounts" msgstr "社交账号" #: socialaccount/models.py:160 msgid "token" msgstr "令牌" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "\"oauth_token\" (OAuth1) 或访问令牌 (OAuth2)" #: socialaccount/models.py:165 msgid "token secret" msgstr "令牌密钥" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "\"oauth_token_secret\" (OAuth1) 或刷新令牌 (OAuth2)" #: socialaccount/models.py:169 msgid "expires at" msgstr "过期时间" #: socialaccount/models.py:174 msgid "social application token" msgstr "社交应用令牌" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "社交应用令牌" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "无效个人资料数据" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 msgid "Login" msgstr "登录" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "取消" #: socialaccount/providers/oauth/client.py:85 #, python-format msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "在请求token时收到无效的响应\"%s\"。响应如下:%s。" #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "从 \"%s\" 获取访问令牌时响应无效。" #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "未保存 \"%s\" 的请求令牌。" #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "未保存 \"%s\" 的访问令牌。" #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "无权访问私有资源 \"%s\"。" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "从 \"%s\" 获取请求令牌时响应无效。" #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "账号未激活" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "此账号未激活。" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 msgid "Confirm Access" msgstr "确认访问" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "请重新验证以保护您的账户安全。" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "可选项" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "Email Confirmation" msgid "Email Verification" msgstr "Email确认" #: templates/account/confirm_email_verification_code.html:9 #, fuzzy #| msgid "Enter an authenticator code:" msgid "Enter Email Verification Code" msgstr "输入身份验证器代码:" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "我们已发送一个代码到 %(email_link)s。该代码将很快过期,请尽快输入。" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "确认" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "登录" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "输入登录代码" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "Email地址" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "以下Email地址已关联到您的帐号:" #: templates/account/email.html:25 msgid "Verified" msgstr "已验证" #: templates/account/email.html:29 msgid "Unverified" msgstr "未验证" #: templates/account/email.html:34 msgid "Primary" msgstr "首选Email" #: templates/account/email.html:44 msgid "Make Primary" msgstr "设置为首选" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "重发验证Email" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "移除" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "添加Email地址" #: templates/account/email.html:70 msgid "Add Email" msgstr "添加Email" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "您真的想移除选定的Email地址吗?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" "您收到这封电子邮件是因为您或其他人尝试使用以下电子邮件地址注册账户:\n" "\n" "%(email)s\n" "\n" "但是,使用该电子邮件地址的账户已经存在。如果您忘记了这一点,请使用密码找回程" "序来恢复您的账户:\n" "\n" "%(password_reset_url)s" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "账户已经存在" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "来自%(site_name)s的 Hello!" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" "感谢您使用 %(site_name)s!\n" "%(site_domain)s" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "您收到这封邮件是因为您的账户产生了以下变动:" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" "如果这不是您做出的更改,请立即采取适当的安全措施。对您的账户的更改来自:\n" "\n" "- IP地址: %(ip)s\n" "- 浏览器: %(user_agent)s\n" "- 日期: %(timestamp)s" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "您的电子邮件已从 %(from_email)s 更改为 %(to_email)s。" #: templates/account/email/email_changed_subject.txt:3 msgid "Email Changed" msgstr "Email已更改" #: templates/account/email/email_confirm_message.txt:4 msgid "Your email has been confirmed." msgstr "您的Email已经被确认。" #: templates/account/email/email_confirm_subject.txt:3 msgid "Email Confirmation" msgstr "Email确认" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "You're receiving this email because user %(user_display)s has given your " #| "email address to register an account on %(site_domain)s.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "您收到此电子邮件是因为用户 %(user_display)s 使用您的电子邮件地址在 " "%(site_domain)s 上注册了一个账户。\n" "\n" "若此操作正确,请访问 %(activate_url)s 进行确认" #: templates/account/email/email_confirmation_message.txt:7 #, fuzzy #| msgid "" #| "Your sign-in code is listed below. Please enter it in your open browser " #| "window." msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "您的登录代码如下所示。请在打开的浏览器窗口中输入。" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 msgid "Please Confirm Your Email Address" msgstr "请确认您的Email地址" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "Email地址 %(deleted_email)s 已从您的账户中移除。" #: templates/account/email/email_deleted_subject.txt:3 msgid "Email Removed" msgstr "Email被移除了" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "您的登录代码如下所示。请在打开的浏览器窗口中输入。" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "如果您没有发起这个操作,您可以安全地忽略这封邮件。" #: templates/account/email/login_code_subject.txt:3 msgid "Sign-In Code" msgstr "登录代码" #: templates/account/email/password_changed_message.txt:4 msgid "Your password has been changed." msgstr "您的密码现已被修改。" #: templates/account/email/password_changed_subject.txt:3 msgid "Password Changed" msgstr "密码已更改" #: templates/account/email/password_reset_key_message.txt:4 msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "您收到此电子邮件是因为您或其他人申请了重置您的用户账户密码。\n" "如果您没有申请重置密码,您可以安全地忽略此邮件。点击下面的链接以重置您的密" "码。" #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "作为提示,您的用户名是%(username)s." #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "密码重置邮件" #: templates/account/email/password_reset_message.txt:4 msgid "Your password has been reset." msgstr "您的密码已被重置。" #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "密码重置" #: templates/account/email/password_set_message.txt:4 msgid "Your password has been set." msgstr "您的密码已被设置。" #: templates/account/email/password_set_subject.txt:3 msgid "Password Set" msgstr "密码设置" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" "您收到这封邮件是因为您或其他人尝试使用电子邮件 %(email)s 访问一个账户。然而," "我们的数据库中没有这个账户的任何记录。" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "如果是您本人,您可以使用下面的链接注册一个账户。" #: templates/account/email/unknown_account_subject.txt:3 msgid "Unknown Account" msgstr "未知账号" #: templates/account/email_change.html:5 templates/account/email_change.html:9 msgid "Email Address" msgstr "Email地址" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 msgid "Current email" msgstr "当前Email" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "改为" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "您的电子邮件地址仍在等待验证。" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "取消变更" #: templates/account/email_change.html:49 msgid "Change to" msgstr "改为" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 msgid "Change Email" msgstr "更改Email" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "确认Email地址" #: templates/account/email_confirm.html:16 #, python-format msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "请确认%(email)s是用户%(user_display)s的电子" "邮件地址。" #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, python-format msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "无法确认%(email)s,因为它已被另一个账户确认。" #: templates/account/email_confirm.html:36 #, python-format msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "这个电子邮件确认链接已过期或无效。请发起新的电子邮" "件确认请求。" #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "如果您还没有创建账号,请先 %(link)s注册%(end_link)s 。" #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "使用 passkey 登录" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "邮寄登录代码给我" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "登出" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "您确定要登出吗?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "您不能删除您的主Email地址 (%(email)s) 。" #: templates/account/messages/email_confirmation_sent.txt:2 #, python-format msgid "Confirmation email sent to %(email)s." msgstr "确认邮件已发往 %(email)s。" #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "您已确认Email地址 %(email)s。" #: templates/account/messages/email_deleted.txt:2 #, python-format msgid "Removed email address %(email)s." msgstr "已移除Email地址 %(email)s。" #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "以 %(name)s 成功登录。" #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "您已登出。" #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "登录代码已发送至 %(email)s。" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "密码修改成功。" #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "密码设置成功。" #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "主Email地址已设置。" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "修改密码" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "忘记密码?" #: templates/account/password_reset.html:14 msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "忘记您的密码了吗?请在下面输入您的电子邮件地址,我们将发送一封电子邮件,让您" "可以重置密码。" #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "重置我的密码" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "如在重置密码时遇到问题,请与我们联系。" #: templates/account/password_reset_done.html:16 msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "我们已经给您发送了一封电子邮件。如果您还没有收到,请检查您的垃圾邮件文件夹。" "否则,如果几分钟内仍未收到,请联系我们。" #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "不正确的 token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "密码重置链接无效,可能是因为它已被使用。请申请新的密码重置。" #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "您的密码现已被修改。" #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "设置密码" #: templates/account/reauthenticate.html:6 msgid "Enter your password:" msgstr "输入您的密码:" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "您将收到一封包含用于免密码登录的特殊代码的电子邮件。" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "请求码" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "其它登录选项" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "注册" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "注册" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "已经有一个账号? 请%(link)s登录%(end_link)s." #: templates/account/signup.html:39 #, fuzzy #| msgid "Sign in with a passkey" msgid "Sign up using a passkey" msgstr "使用 passkey 登录" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "注册" #: templates/account/signup_by_passkey.html:36 #, fuzzy #| msgid "Other sign-in options" msgid "Other options" msgstr "其它登录选项" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "注册关闭" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "非常抱歉,当前已关闭注册。" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "注意" #: templates/account/snippets/already_logged_in.html:7 #, python-format msgid "You are already logged in as %(user_display)s." msgstr "您已以 %(user_display)s 的身份登录。" #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "警告:" #: templates/account/snippets/warn_no_email.html:3 msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "您当前未设置任何电子邮件地址。您真的应该添加一个电子邮件地址,以便接收通知," "重置密码等。" #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "验证您的Email地址" #: templates/account/verification_sent.html:12 msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "我们已向您发送了一封验证邮件。请按照邮件中提供的链接完成注册流程。如果您在主" "收件箱中看不到验证邮件,请检查您的垃圾邮件文件夹。如果几分钟内还没有收到验证" "邮件,请联系我们。" #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "本站的这部分需要我们验证您的身份真实性。为此,我们需要您验证您的电子邮件地址" "的所有权。" #: templates/account/verified_email_required.html:18 msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "我们已向您发送了一封用于验证的电子邮件。请点击邮件内的链接。如果您在主收件箱" "中找不到该验证邮件,请检查您的垃圾邮件文件夹。否则,如果几分钟内还未收到,请" "联系我们。" #: templates/account/verified_email_required.html:23 #, python-format msgid "" "Note: you can still change your " "email address." msgstr "" "注意:您仍然可以更改您的电子邮件地" "址。" #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "消息:" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "菜单:" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "账号连接" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "双因素身份认证" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "会话" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "您的帐户已受到双因素身份认证的保护。请输入身份验证器代码:" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "已生成一组新的双因素身份认证恢复代码。" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "已生成新的恢复代码" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "身份验证器应用已激活。" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "身份验证器应用已激活" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "身份验证器应用已停用。" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "身份验证器应用已停用" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "已添加新的安全密钥。" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "已添加新的密钥" #: templates/mfa/email/webauthn_removed_message.txt:4 msgid "A security key has been removed." msgstr "一个安全密钥已被移除。" #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "密钥已被移除" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "身份验证器应用" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "使用身份验证器应用进行身份验证处于活动状态。" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "未激活身份验证器应用。" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "停用" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "激活" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "安全密钥" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "您已添加%(count)s个安全密钥。" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "未添加安全密钥。" #: templates/mfa/index.html:62 msgid "Manage" msgstr "管理" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 msgid "Add" msgstr "添加" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "恢复代码" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "在 %(total_count)s个恢复码中,有 %(unused_count)s 个可用。" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "未设置恢复代码。" #: templates/mfa/index.html:96 msgid "View" msgstr "查看" #: templates/mfa/index.html:102 msgid "Download" msgstr "下载" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "生成" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "已生成新的恢复代码集。" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "已添加安全密钥。" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "已移除安全密钥。" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "输入身份验证器代码:" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "您即将为您的帐户生成一组新的恢复代码。" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "此操作将使您现有的代码失效。" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "确定要执行此操作吗?" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "未使用的代码" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "下载代码" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "生成新代码" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "激活身份验证器应用" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" "为使用双因素验证保护您的帐户,您需要使用身份验证器应用扫描下方的二维码。然" "后,在下方输入应用生成的验证代码。" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "身份验证器密钥" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "您可以保存此密钥,以便以后重新安装您的身份验证器应用程序。" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "停用身份验证器应用" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "您即将停用基于身份验证器应用的身份验证。确定要执行此操作吗?" #: templates/mfa/webauthn/add_form.html:7 msgid "Add Security Key" msgstr "添加安全密钥" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 msgid "Remove Security Key" msgstr "移除安全密钥" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 msgid "Are you sure you want to remove this security key?" msgstr "您确定要移除此安全密钥吗?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "用途" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "Passkey" #: templates/mfa/webauthn/authenticator_list.html:37 msgid "Security key" msgstr "安全密钥" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "此密钥未表明其是否为 passkey。" #: templates/mfa/webauthn/authenticator_list.html:41 msgid "Unspecified" msgstr "未指定" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "添加于 %(created_at)s" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "上次使用:%(last_used)s" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "编辑" #: templates/mfa/webauthn/edit_form.html:7 msgid "Edit Security Key" msgstr "编辑安全密钥" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "保存" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Passkey" msgid "Create Passkey" msgstr "Passkey" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "已建立" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "此功能需要 JavaScript。" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 msgid "Third-Party Login Failure" msgstr "第三方登录失败" #: templates/socialaccount/authentication_error.html:12 msgid "" "An error occurred while attempting to login via your third-party account." msgstr "尝试通过您的第三方账户登录时发生错误。" #: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "您可以使用以下任一第三方账号登录您的账户:" #: templates/socialaccount/connections.html:46 msgid "You currently have no third-party accounts connected to this account." msgstr "您当前没有与此账户关联的第三方账号。" #: templates/socialaccount/connections.html:50 msgid "Add a Third-Party Account" msgstr "添加一个第三方账号" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "已连接来自 %(provider)s 的第三方账号到您的账户。" #: templates/socialaccount/email/account_connected_subject.txt:3 msgid "Third-Party Account Connected" msgstr "第三方账号已连接" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "已从您的账户断开来自 %(provider)s 的第三方账号连接。" #: templates/socialaccount/email/account_disconnected_subject.txt:3 msgid "Third-Party Account Disconnected" msgstr "第三方账号已断开" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "连接 %(provider)s" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "您即将连接一个新的来自 %(provider)s 的第三方账号。" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "通过 %(provider)s 登录" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "您即将使用来自 %(provider)s 的第三方账号登录。" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "继续" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "登录已取消" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "您决定取消使用您的已有账号登录我们的网站。如果这是一个失误,请继续登录." #: templates/socialaccount/messages/account_connected.txt:2 msgid "The third-party account has been connected." msgstr "第三方账号已连接。" #: templates/socialaccount/messages/account_disconnected.txt:2 msgid "The third-party account has been disconnected." msgstr "第三方账号已断开连接。" #: templates/socialaccount/signup.html:12 #, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "您即将使用您的 %(provider_name)s 账号登录到\n" "%(site_name)s。作为最后一步,请完成以下表单:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "或使用第三方" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "已退出所有其他会话。" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "开始时间" #: templates/usersessions/usersession_list.html:24 msgid "IP Address" msgstr "IP地址" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "浏览器" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "上次查看于" #: templates/usersessions/usersession_list.html:47 msgid "Current" msgstr "当前" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "注销其他会话" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "用户会话" #: usersessions/models.py:92 msgid "session key" msgstr "会话密钥" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "账号连接" #~ msgid "Use security key or device" #~ msgstr "请使用安全密钥或设备" #~ msgid "Add Security Key or Device" #~ msgstr "添加安全密钥或设备" #~ msgid "Add key or device" #~ msgstr "添加密钥或设备" #~ msgid "Security Keys and Devices" #~ msgstr "安全密钥和设备" #~ msgid "You have not added any security keys/devices." #~ msgstr "您尚未添加任何安全密钥/设备。" #~ msgid "Edit Security Key or Device" #~ msgstr "编辑安全密钥或设备" django-allauth-65.0.2/allauth/locale/zh_Hant/000077500000000000000000000000001467545753200210045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/zh_Hant/LC_MESSAGES/000077500000000000000000000000001467545753200225715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/locale/zh_Hant/LC_MESSAGES/django.po000066400000000000000000001537631467545753200244120ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-21 06:42-0500\n" "PO-Revision-Date: 2024-07-03 05:09+0000\n" "Last-Translator: hugoalh \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.7-dev\n" #: account/adapter.py:51 msgid "This account is currently inactive." msgstr "此帳號目前沒有啟用。" #: account/adapter.py:53 msgid "You cannot remove your primary email address." msgstr "你不能移除你的主要電子郵件地址。" #: account/adapter.py:56 msgid "This email address is already associated with this account." msgstr "此電子郵件地址已經與此帳號連結了。" #: account/adapter.py:59 msgid "The email address and/or password you specified are not correct." msgstr "你提供的電子郵件地址和/或密碼不正確。" #: account/adapter.py:61 msgid "A user is already registered with this email address." msgstr "已經有使用者使用此電子郵件地址註冊。" #: account/adapter.py:62 msgid "Please type your current password." msgstr "請輸入你目前的密碼。" #: account/adapter.py:63 mfa/adapter.py:40 msgid "Incorrect code." msgstr "不正確的代碼。" #: account/adapter.py:64 msgid "Incorrect password." msgstr "不正確的密碼。" #: account/adapter.py:65 msgid "Invalid or expired key." msgstr "無效或已過期的金鑰。" #: account/adapter.py:66 msgid "The password reset token was invalid." msgstr "密碼重置令牌無效。" #: account/adapter.py:67 #, python-format msgid "You cannot add more than %d email addresses." msgstr "你不能新增超過 %d 個電子郵件地址。" #: account/adapter.py:69 msgid "Too many failed login attempts. Try again later." msgstr "登入嘗試失敗次數過多。請稍後再試。" #: account/adapter.py:71 msgid "The email address is not assigned to any user account" msgstr "此電子郵件地址未分配給任何使用者帳號" #: account/adapter.py:72 #: templates/account/messages/unverified_primary_email.txt:2 msgid "Your primary email address must be verified." msgstr "你的主要電子郵件地址必須已驗證。" #: account/adapter.py:74 msgid "Username can not be used. Please use other username." msgstr "無法使用此使用者名稱。請使用其他使用者名稱。" #: account/adapter.py:77 msgid "The username and/or password you specified are not correct." msgstr "你提供的使用者名稱和/或密碼不正確。" #: account/adapter.py:741 msgid "Use your password" msgstr "使用你的密碼" #: account/adapter.py:750 msgid "Use authenticator app or code" msgstr "使用驗證器應用程式或代碼" #: account/adapter.py:757 templates/mfa/authenticate.html:36 #: templates/mfa/webauthn/reauthenticate.html:15 #, fuzzy #| msgid "secret key" msgid "Use a security key" msgstr "secret key" #: account/admin.py:23 msgid "Mark selected email addresses as verified" msgstr "標記已選取的電子郵件地址為已驗證" #: account/apps.py:11 msgid "Accounts" msgstr "帳號" #: account/forms.py:57 account/forms.py:483 msgid "You must type the same password each time." msgstr "你必須每次輸入相同的密碼。" #: account/forms.py:92 account/forms.py:413 account/forms.py:573 #: account/forms.py:685 msgid "Password" msgstr "密碼" #: account/forms.py:93 msgid "Remember Me" msgstr "記住我" #: account/forms.py:103 account/forms.py:270 account/forms.py:499 #: account/forms.py:591 account/forms.py:702 msgid "Email address" msgstr "電子郵件地址" #: account/forms.py:107 account/forms.py:308 account/forms.py:496 #: account/forms.py:586 msgid "Email" msgstr "電子郵件" #: account/forms.py:110 account/forms.py:113 account/forms.py:260 #: account/forms.py:263 msgid "Username" msgstr "使用者名稱" #: account/forms.py:123 msgid "Username or email" msgstr "使用者名稱或電子郵件" #: account/forms.py:126 msgctxt "field label" msgid "Login" msgstr "登入" #: account/forms.py:137 msgid "Forgot your password?" msgstr "忘記你的密碼?" #: account/forms.py:299 msgid "Email (again)" msgstr "電子郵件(再次)" #: account/forms.py:303 msgid "Email address confirmation" msgstr "電子郵件地址確認" #: account/forms.py:311 msgid "Email (optional)" msgstr "電子郵件(選擇性)" #: account/forms.py:370 msgid "You must type the same email each time." msgstr "你必須每次輸入相同的電子郵件。" #: account/forms.py:419 account/forms.py:574 msgid "Password (again)" msgstr "密碼(再次)" #: account/forms.py:554 msgid "Current Password" msgstr "目前密碼" #: account/forms.py:556 account/forms.py:638 msgid "New Password" msgstr "新密碼" #: account/forms.py:557 account/forms.py:639 msgid "New Password (again)" msgstr "新密碼(再次)" #: account/forms.py:725 account/forms.py:727 mfa/base/forms.py:15 #: mfa/base/forms.py:17 mfa/totp/forms.py:13 msgid "Code" msgstr "代碼" #: account/models.py:26 msgid "user" msgstr "使用者" #: account/models.py:32 account/models.py:40 account/models.py:147 msgid "email address" msgstr "電子郵件地址" #: account/models.py:34 msgid "verified" msgstr "已驗證" #: account/models.py:35 msgid "primary" msgstr "主要" #: account/models.py:41 msgid "email addresses" msgstr "電子郵件地址" #: account/models.py:150 msgid "created" msgstr "已建立" #: account/models.py:151 msgid "sent" msgstr "已傳送" #: account/models.py:152 socialaccount/models.py:69 msgid "key" msgstr "金鑰" #: account/models.py:157 msgid "email confirmation" msgstr "電子郵件確認" #: account/models.py:158 msgid "email confirmations" msgstr "電子郵件確認" #: headless/apps.py:7 msgid "Headless" msgstr "無頭" #: mfa/adapter.py:32 msgid "" "You cannot add an email address to an account protected by two-factor " "authentication." msgstr "你不能將電子郵件地址新增至受雙重驗證保護的帳號。" #: mfa/adapter.py:35 msgid "You cannot deactivate two-factor authentication." msgstr "你不能停用雙重驗證。" #: mfa/adapter.py:38 msgid "" "You cannot generate recovery codes without having two-factor authentication " "enabled." msgstr "你不能在未啟用雙重驗證下產生復原代碼。" #: mfa/adapter.py:42 msgid "" "You cannot activate two-factor authentication until you have verified your " "email address." msgstr "你不能在驗證你的電子郵件地址之前啟用雙重驗證。" #: mfa/adapter.py:141 msgid "Master key" msgstr "主要金鑰" #: mfa/adapter.py:143 msgid "Backup key" msgstr "備份金鑰" #: mfa/adapter.py:144 #, python-brace-format msgid "Key nr. {number}" msgstr "" #: mfa/apps.py:9 msgid "MFA" msgstr "多重要素驗證" #: mfa/models.py:24 msgid "Recovery codes" msgstr "恢復代碼" #: mfa/models.py:25 msgid "TOTP Authenticator" msgstr "TOTP 驗證器" #: mfa/models.py:26 msgid "WebAuthn" msgstr "WebAuthn" #: mfa/totp/forms.py:11 msgid "Authenticator code" msgstr "驗證器代碼" #: mfa/webauthn/forms.py:56 msgid "Passwordless" msgstr "無密碼" #: mfa/webauthn/forms.py:59 #, fuzzy #| msgid "" #| "Enabling passwordless operation allows you to sign in using just this key/" #| "device, but imposes additional requirements such as biometrics or PIN " #| "protection." msgid "" "Enabling passwordless operation allows you to sign in using just this key, " "but imposes additional requirements such as biometrics or PIN protection." msgstr "" "啟用無密碼操作可以讓你僅使用此金鑰/裝置登入,但會提出其他要求,例如生物辨識" "或 PIN 保護。" #: socialaccount/adapter.py:36 #, fuzzy, python-format #| msgid "" #| "An account already exists with this e-mail address. Please sign in to " #| "that account first, then connect your %s account." msgid "" "An account already exists with this email address. Please sign in to that " "account first, then connect your %s account." msgstr "" "已經有一個帳號與此電子郵件連結了,請先登入該帳號,然後連接你的 %s 帳號。" #: socialaccount/adapter.py:40 msgid "Invalid token." msgstr "無效的令牌。" #: socialaccount/adapter.py:41 msgid "Your account has no password set up." msgstr "您的帳號沒有設置密碼。" #: socialaccount/adapter.py:42 msgid "Your account has no verified email address." msgstr "您的帳號下沒有驗證過的電子郵件地址。" #: socialaccount/adapter.py:44 msgid "You cannot disconnect your last remaining third-party account." msgstr "你無法斷開你最後一個的第三方帳戶。" #: socialaccount/adapter.py:47 #: templates/socialaccount/messages/account_connected_other.txt:2 #, fuzzy #| msgid "The social account is already connected to a different account." msgid "The third-party account is already connected to a different account." msgstr "這個社群網站帳號已經與另一個帳號連結過了。" #: socialaccount/apps.py:9 msgid "Social Accounts" msgstr "社群帳號" #: socialaccount/models.py:44 socialaccount/models.py:97 msgid "provider" msgstr "提供者" #: socialaccount/models.py:52 #, fuzzy #| msgid "provider" msgid "provider ID" msgstr "提供者" #: socialaccount/models.py:56 msgid "name" msgstr "名稱" #: socialaccount/models.py:58 msgid "client id" msgstr "client id" #: socialaccount/models.py:60 msgid "App ID, or consumer key" msgstr "應用程式 ID 或消費者金鑰" #: socialaccount/models.py:63 msgid "secret key" msgstr "秘密金鑰" #: socialaccount/models.py:66 msgid "API secret, client secret, or consumer secret" msgstr "API 秘密、客戶秘密或消費者秘密" #: socialaccount/models.py:69 templates/mfa/webauthn/authenticator_list.html:18 msgid "Key" msgstr "金鑰" #: socialaccount/models.py:81 msgid "social application" msgstr "社群應用程式" #: socialaccount/models.py:82 msgid "social applications" msgstr "社群應用程式" #: socialaccount/models.py:117 msgid "uid" msgstr "使用者 ID" #: socialaccount/models.py:119 msgid "last login" msgstr "最後一次登入" #: socialaccount/models.py:120 msgid "date joined" msgstr "加入日期" #: socialaccount/models.py:121 msgid "extra data" msgstr "額外資料" #: socialaccount/models.py:125 msgid "social account" msgstr "社群帳號" #: socialaccount/models.py:126 msgid "social accounts" msgstr "社群帳號" #: socialaccount/models.py:160 msgid "token" msgstr "" #: socialaccount/models.py:161 msgid "\"oauth_token\" (OAuth1) or access token (OAuth2)" msgstr "" #: socialaccount/models.py:165 msgid "token secret" msgstr "" #: socialaccount/models.py:166 msgid "\"oauth_token_secret\" (OAuth1) or refresh token (OAuth2)" msgstr "" #: socialaccount/models.py:169 msgid "expires at" msgstr "過期日" #: socialaccount/models.py:174 msgid "social application token" msgstr "社群應用程式 Token" #: socialaccount/models.py:175 msgid "social application tokens" msgstr "社群應用程式 Token" #: socialaccount/providers/douban/views.py:36 msgid "Invalid profile data" msgstr "" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:16 #, fuzzy #| msgctxt "field label" #| msgid "Login" msgid "Login" msgstr "登入" #: socialaccount/providers/dummy/templates/dummy/authenticate_form.html:19 #: templates/account/confirm_email_verification_code.html:33 #: templates/account/confirm_email_verification_code.html:37 #: templates/account/confirm_login_code.html:32 #: templates/mfa/authenticate.html:40 #: templates/mfa/webauthn/signup_form.html:26 msgid "Cancel" msgstr "" #: socialaccount/providers/oauth/client.py:85 #, fuzzy, python-format #| msgid "Invalid response while obtaining request token from \"%s\"." msgid "" "Invalid response while obtaining request token from \"%s\". Response was: %s." msgstr "Invalid response while obtaining request token from \"%s\"." #: socialaccount/providers/oauth/client.py:119 #: socialaccount/providers/pocket/client.py:86 #, python-format msgid "Invalid response while obtaining access token from \"%s\"." msgstr "Invalid response while obtaining access token from \"%s\"." #: socialaccount/providers/oauth/client.py:140 #, python-format msgid "No request token saved for \"%s\"." msgstr "No request token saved for \"%s\"." #: socialaccount/providers/oauth/client.py:191 #, python-format msgid "No access token saved for \"%s\"." msgstr "No access token saved for \"%s\"." #: socialaccount/providers/oauth/client.py:212 #, python-format msgid "No access to private resources at \"%s\"." msgstr "無權訪問私有資源 \"%s\"。" #: socialaccount/providers/pocket/client.py:41 #, python-format msgid "Invalid response while obtaining request token from \"%s\"." msgstr "Invalid response while obtaining request token from \"%s\"." #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" msgstr "帳號未啟用" #: templates/account/account_inactive.html:12 msgid "This account is inactive." msgstr "此帳號未啟用。" #: templates/account/base_reauthenticate.html:5 #: templates/account/base_reauthenticate.html:9 #, fuzzy #| msgid "Confirm Email Address" msgid "Confirm Access" msgstr "確認電子郵件" #: templates/account/base_reauthenticate.html:12 msgid "Please reauthenticate to safeguard your account." msgstr "" #: templates/account/base_reauthenticate.html:19 #: templates/mfa/authenticate.html:31 msgid "Alternative options" msgstr "" #: templates/account/confirm_email_verification_code.html:5 #, fuzzy #| msgid "email confirmation" msgid "Email Verification" msgstr "電子郵件確認" #: templates/account/confirm_email_verification_code.html:9 msgid "Enter Email Verification Code" msgstr "" #: templates/account/confirm_email_verification_code.html:15 #: templates/account/confirm_login_code.html:15 #, python-format msgid "" "We’ve sent a code to %(email_link)s. The code expires shortly, so please " "enter it soon." msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:24 #: templates/account/reauthenticate.html:18 #: templates/mfa/reauthenticate.html:18 msgid "Confirm" msgstr "確認" #: templates/account/confirm_login_code.html:5 #: templates/account/confirm_login_code.html:27 templates/account/login.html:5 #: templates/account/login.html:9 templates/account/login.html:31 #: templates/account/request_login_code.html:5 #: templates/allauth/layouts/base.html:68 templates/mfa/authenticate.html:6 #: templates/mfa/authenticate.html:24 templates/openid/login.html:5 #: templates/openid/login.html:9 templates/openid/login.html:20 #: templates/socialaccount/login.html:5 #: templates/socialaccount/login_redirect.html:5 msgid "Sign In" msgstr "登入" #: templates/account/confirm_login_code.html:9 msgid "Enter Sign-In Code" msgstr "" #: templates/account/email.html:4 templates/account/email.html:8 msgid "Email Addresses" msgstr "電子郵件地址" #: templates/account/email.html:12 msgid "The following email addresses are associated with your account:" msgstr "下列電子郵件已與你的帳號連結:" #: templates/account/email.html:25 msgid "Verified" msgstr "已驗證" #: templates/account/email.html:29 msgid "Unverified" msgstr "未驗證" #: templates/account/email.html:34 msgid "Primary" msgstr "主要的" #: templates/account/email.html:44 msgid "Make Primary" msgstr "設為主要的" #: templates/account/email.html:47 templates/account/email_change.html:37 msgid "Re-send Verification" msgstr "重寄驗証信" #: templates/account/email.html:50 #: templates/mfa/webauthn/authenticator_confirm_delete.html:16 #: templates/mfa/webauthn/authenticator_list.html:60 #: templates/socialaccount/connections.html:40 msgid "Remove" msgstr "移除" #: templates/account/email.html:59 msgid "Add Email Address" msgstr "增加電子郵件" #: templates/account/email.html:70 msgid "Add Email" msgstr "增加電子郵件" #: templates/account/email.html:79 msgid "Do you really want to remove the selected email address?" msgstr "您真的要移除所選擇電子郵件嗎?" #: templates/account/email/account_already_exists_message.txt:4 #, python-format msgid "" "You are receiving this email because you or someone else tried to signup for " "an\n" "account using email address:\n" "\n" "%(email)s\n" "\n" "However, an account using that email address already exists. In case you " "have\n" "forgotten about this, please use the password forgotten procedure to " "recover\n" "your account:\n" "\n" "%(password_reset_url)s" msgstr "" #: templates/account/email/account_already_exists_subject.txt:3 msgid "Account Already Exists" msgstr "" #: templates/account/email/base_message.txt:1 #, python-format msgid "Hello from %(site_name)s!" msgstr "" #: templates/account/email/base_message.txt:5 #, python-format msgid "" "Thank you for using %(site_name)s!\n" "%(site_domain)s" msgstr "" #: templates/account/email/base_notification.txt:5 msgid "" "You are receiving this mail because the following change was made to your " "account:" msgstr "" #: templates/account/email/base_notification.txt:10 #, python-format msgid "" "If you do not recognize this change then please take proper security " "precautions immediately. The change to your account originates from:\n" "\n" "- IP address: %(ip)s\n" "- Browser: %(user_agent)s\n" "- Date: %(timestamp)s" msgstr "" #: templates/account/email/email_changed_message.txt:4 #, python-format msgid "Your email has been changed from %(from_email)s to %(to_email)s." msgstr "" #: templates/account/email/email_changed_subject.txt:3 #, fuzzy #| msgid "Email address" msgid "Email Changed" msgstr "電子郵件地址" #: templates/account/email/email_confirm_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your email has been confirmed." msgstr "您的密码已被删除。" #: templates/account/email/email_confirm_subject.txt:3 #, fuzzy #| msgid "email confirmation" msgid "Email Confirmation" msgstr "電子郵件確認" #: templates/account/email/email_confirmation_message.txt:5 #, fuzzy, python-format #| msgid "" #| "User %(user_display)s at %(site_name)s has given this as an email " #| "address.\n" #| "\n" #| "To confirm this is correct, go to %(activate_url)s\n" msgid "" "You're receiving this email because user %(user_display)s has given your " "email address to register an account on %(site_domain)s." msgstr "" "網站%(site_name)s上的使用者%(user_display)s將此設為他的電子郵件地址。\n" "\n" "為了確認這是正確的,請開啟這個連結: %(activate_url)s\n" #: templates/account/email/email_confirmation_message.txt:7 msgid "" "Your email verification code is listed below. Please enter it in your open " "browser window." msgstr "" #: templates/account/email/email_confirmation_message.txt:9 #, python-format msgid "To confirm this is correct, go to %(activate_url)s" msgstr "" #: templates/account/email/email_confirmation_subject.txt:3 #, fuzzy #| msgid "Confirm Email Address" msgid "Please Confirm Your Email Address" msgstr "確認電子郵件" #: templates/account/email/email_deleted_message.txt:4 #, python-format msgid "Email address %(deleted_email)s has been removed from your account." msgstr "" #: templates/account/email/email_deleted_subject.txt:3 #, fuzzy #| msgid "Remove" msgid "Email Removed" msgstr "移除" #: templates/account/email/login_code_message.txt:5 msgid "" "Your sign-in code is listed below. Please enter it in your open browser " "window." msgstr "" #: templates/account/email/login_code_message.txt:9 #: templates/account/email/unknown_account_message.txt:6 msgid "This mail can be safely ignored if you did not initiate this action." msgstr "" #: templates/account/email/login_code_subject.txt:3 #, fuzzy #| msgid "Sign In" msgid "Sign-In Code" msgstr "登入" #: templates/account/email/password_changed_message.txt:4 #, fuzzy #| msgid "Your password is now changed." msgid "Your password has been changed." msgstr "您的密碼已變更。" #: templates/account/email/password_changed_subject.txt:3 #, fuzzy #| msgid "Password (again)" msgid "Password Changed" msgstr "密碼 (再一次)" #: templates/account/email/password_reset_key_message.txt:4 #, fuzzy #| msgid "" #| "You're receiving this e-mail because you or someone else has requested a " #| "password for your user account at %(site_domain)s.\n" #| "It can be safely ignored if you did not request a password reset. Click " #| "the link below to reset your password." msgid "" "You're receiving this email because you or someone else has requested a " "password reset for your user account.\n" "It can be safely ignored if you did not request a password reset. Click the " "link below to reset your password." msgstr "" "您會收到這封信是因為您或是某人在 %(site_domain)s 這個網站上要求重設您帳號的密" "碼。\n" "若您沒有要求我們重設密碼,請您直接忽略這封信。若要重設您的密碼,請點擊下面的" "連結。" #: templates/account/email/password_reset_key_message.txt:9 #, python-format msgid "In case you forgot, your username is %(username)s." msgstr "提醒您,您的使用者名稱是 %(username)s 。" #: templates/account/email/password_reset_key_subject.txt:3 msgid "Password Reset Email" msgstr "密碼重設電子郵件" #: templates/account/email/password_reset_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been reset." msgstr "您的密码已被删除。" #: templates/account/email/password_reset_subject.txt:3 #: templates/account/password_reset.html:4 #: templates/account/password_reset.html:8 #: templates/account/password_reset_done.html:6 #: templates/account/password_reset_done.html:10 msgid "Password Reset" msgstr "密碼重設" #: templates/account/email/password_set_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "Your password has been set." msgstr "您的密码已被删除。" #: templates/account/email/password_set_subject.txt:3 #, fuzzy #| msgid "Password Reset" msgid "Password Set" msgstr "密碼重設" #: templates/account/email/unknown_account_message.txt:4 #, python-format msgid "" "You are receiving this email because you, or someone else, tried to access " "an account with email %(email)s. However, we do not have any record of such " "an account in our database." msgstr "" #: templates/account/email/unknown_account_message.txt:8 msgid "If it was you, you can sign up for an account using the link below." msgstr "" #: templates/account/email/unknown_account_subject.txt:3 #, fuzzy #| msgid "Account" msgid "Unknown Account" msgstr "帳號" #: templates/account/email_change.html:5 templates/account/email_change.html:9 #, fuzzy #| msgid "Email Addresses" msgid "Email Address" msgstr "電子郵件地址" #: templates/account/email_change.html:21 #: templates/account/email_change.html:29 #, fuzzy #| msgid "Current Password" msgid "Current email" msgstr "目前密碼" #: templates/account/email_change.html:31 msgid "Changing to" msgstr "" #: templates/account/email_change.html:35 msgid "Your email address is still pending verification." msgstr "你的電子郵件地址仍在等待驗證。" #: templates/account/email_change.html:41 msgid "Cancel Change" msgstr "" #: templates/account/email_change.html:49 #, fuzzy #| msgid "Email" msgid "Change to" msgstr "E-mail" #: templates/account/email_change.html:55 #: templates/allauth/layouts/base.html:31 #, fuzzy #| msgid "Email" msgid "Change Email" msgstr "E-mail" #: templates/account/email_confirm.html:6 #: templates/account/email_confirm.html:10 msgid "Confirm Email Address" msgstr "確認電子郵件" #: templates/account/email_confirm.html:16 #, fuzzy, python-format #| msgid "" #| "Please confirm that %(email)s is an e-" #| "mail address for user %(user_display)s." msgid "" "Please confirm that %(email)s is an email " "address for user %(user_display)s." msgstr "" "請確認%(email)s是否是使用者 " "%(user_display)s 的電子郵件地址。" #: templates/account/email_confirm.html:30 #: templates/account/messages/email_confirmation_failed.txt:2 #, fuzzy, python-format #| msgid "The social account is already connected to a different account." msgid "" "Unable to confirm %(email)s because it is already confirmed by a different " "account." msgstr "這個社群網站帳號已經與另一個帳號連結過了。" #: templates/account/email_confirm.html:36 #, fuzzy, python-format #| msgid "" #| "This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." msgid "" "This email confirmation link expired or is invalid. Please issue a new email confirmation request." msgstr "" "電子郵件確認連結已經過期或失效了,請點擊 以要求發" "送新的電子郵件確認信。" #: templates/account/login.html:19 #, python-format msgid "" "If you have not created an account yet, then please %(link)ssign " "up%(end_link)s first." msgstr "若你沒有帳號,請先 %(link)s註冊%(end_link)s 。" #: templates/account/login.html:42 msgid "Sign in with a passkey" msgstr "" #: templates/account/login.html:47 templates/account/request_login_code.html:9 msgid "Mail me a sign-in code" msgstr "" #: templates/account/logout.html:4 templates/account/logout.html:8 #: templates/account/logout.html:21 templates/allauth/layouts/base.html:61 #: templates/usersessions/usersession_list.html:64 msgid "Sign Out" msgstr "登出" #: templates/account/logout.html:11 msgid "Are you sure you want to sign out?" msgstr "您確定要登出嗎?" #: templates/account/messages/cannot_delete_primary_email.txt:2 #, python-format msgid "You cannot remove your primary email address (%(email)s)." msgstr "您不能移除您的主要的電子郵件地址 (%(email)s) 。" #: templates/account/messages/email_confirmation_sent.txt:2 #, fuzzy, python-format msgid "Confirmation email sent to %(email)s." msgstr "確認信已發至 %(email)s 。" #: templates/account/messages/email_confirmed.txt:2 #, python-format msgid "You have confirmed %(email)s." msgstr "你已確認 %(email)s。" #: templates/account/messages/email_deleted.txt:2 #, fuzzy, python-format msgid "Removed email address %(email)s." msgstr "電子郵件地址 %(email)s 已刪除。" #: templates/account/messages/logged_in.txt:4 #, python-format msgid "Successfully signed in as %(name)s." msgstr "成功以 %(name)s..的身份登入。" #: templates/account/messages/logged_out.txt:2 msgid "You have signed out." msgstr "您已登出。" #: templates/account/messages/login_code_sent.txt:2 #, python-format msgid "A sign-in code has been mailed to %(email)s." msgstr "" #: templates/account/messages/password_changed.txt:2 msgid "Password successfully changed." msgstr "密碼修改完成。" #: templates/account/messages/password_set.txt:2 msgid "Password successfully set." msgstr "密碼設定完成。" #: templates/account/messages/primary_email_set.txt:2 msgid "Primary email address set." msgstr "已設定好主要的電子郵件地址。" #: templates/account/password_change.html:4 #: templates/account/password_change.html:8 #: templates/account/password_change.html:20 #: templates/account/password_reset_from_key.html:5 #: templates/account/password_reset_from_key.html:12 #: templates/account/password_reset_from_key.html:30 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:9 #: templates/allauth/layouts/base.html:37 msgid "Change Password" msgstr "修改密碼" #: templates/account/password_change.html:22 msgid "Forgot Password?" msgstr "忘記密碼了?" #: templates/account/password_reset.html:14 #, fuzzy #| msgid "" #| "Forgotten your password? Enter your e-mail address below, and we'll send " #| "you an e-mail allowing you to reset it." msgid "" "Forgotten your password? Enter your email address below, and we'll send you " "an email allowing you to reset it." msgstr "" "忘記您的密碼了嗎? 請在下方輸入您的電子郵件,我們會發送一封電子郵件給您,以便" "重新設定您的密碼。" #: templates/account/password_reset.html:25 msgid "Reset My Password" msgstr "重設我的密碼" #: templates/account/password_reset.html:30 msgid "Please contact us if you have any trouble resetting your password." msgstr "如果在重設密碼時碰到問題,請與我們聯絡。" #: templates/account/password_reset_done.html:16 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent you an email. If you have not received it please check your " "spam folder. Otherwise contact us if you do not receive it in a few minutes." msgstr "" "我們剛剛寄了一封電子郵件確認信給您,\n" "請點擊郵件中的連結。您在數分鐘內尚無法收到郵件,請與我們聯絡。" #: templates/account/password_reset_from_key.html:10 msgid "Bad Token" msgstr "Bad Token" #: templates/account/password_reset_from_key.html:18 #, python-format msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." msgstr "" "密碼重設連結已失效,可能是因為該連結已經被人用過了,請重新申請重設密碼。" #: templates/account/password_reset_from_key_done.html:12 msgid "Your password is now changed." msgstr "您的密碼已變更。" #: templates/account/password_set.html:5 templates/account/password_set.html:9 #: templates/account/password_set.html:21 msgid "Set Password" msgstr "設定密碼" #: templates/account/reauthenticate.html:6 #, fuzzy #| msgid "Forgot Password?" msgid "Enter your password:" msgstr "忘記密碼了?" #: templates/account/request_login_code.html:12 msgid "" "You will receive an email containing a special code for a password-free sign-" "in." msgstr "" #: templates/account/request_login_code.html:24 msgid "Request Code" msgstr "" #: templates/account/request_login_code.html:30 msgid "Other sign-in options" msgstr "" #: templates/account/signup.html:4 templates/account/signup_by_passkey.html:4 #: templates/socialaccount/signup.html:5 msgid "Signup" msgstr "註冊" #: templates/account/signup.html:8 templates/account/signup.html:30 #: templates/account/signup_by_passkey.html:29 #: templates/allauth/layouts/base.html:74 templates/socialaccount/signup.html:9 #: templates/socialaccount/signup.html:25 msgid "Sign Up" msgstr "註冊" #: templates/account/signup.html:17 templates/account/signup_by_passkey.html:17 #, python-format msgid "Already have an account? Then please %(link)ssign in%(end_link)s." msgstr "已有帳號了嗎?請%(link)s登入%(end_link)s." #: templates/account/signup.html:39 msgid "Sign up using a passkey" msgstr "" #: templates/account/signup_by_passkey.html:8 #, fuzzy #| msgid "Sign Up" msgid "Passkey Sign Up" msgstr "註冊" #: templates/account/signup_by_passkey.html:36 msgid "Other options" msgstr "" #: templates/account/signup_closed.html:5 #: templates/account/signup_closed.html:9 msgid "Sign Up Closed" msgstr "註冊未開放" #: templates/account/signup_closed.html:12 msgid "We are sorry, but the sign up is currently closed." msgstr "很抱歉,目前不開放註冊。" #: templates/account/snippets/already_logged_in.html:7 msgid "Note" msgstr "注意" #: templates/account/snippets/already_logged_in.html:7 #, fuzzy, python-format #| msgid "you are already logged in as %(user_display)s." msgid "You are already logged in as %(user_display)s." msgstr "您已經以 %(user_display)s 的身份登入了。" #: templates/account/snippets/warn_no_email.html:3 msgid "Warning:" msgstr "警告:" #: templates/account/snippets/warn_no_email.html:3 #, fuzzy #| msgid "" #| "You currently do not have any e-mail address set up. You should really " #| "add an e-mail address so you can receive notifications, reset your " #| "password, etc." msgid "" "You currently do not have any email address set up. You should really add an " "email address so you can receive notifications, reset your password, etc." msgstr "" "您尚未設定任何電子郵件。建議您最好設定一個電子郵件,以便您接收通知或重新設定" "密碼等等。" #: templates/account/verification_sent.html:5 #: templates/account/verification_sent.html:9 #: templates/account/verified_email_required.html:5 #: templates/account/verified_email_required.html:9 msgid "Verify Your Email Address" msgstr "驗證您的電子郵件地址" #: templates/account/verification_sent.html:12 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for verification. Follow the link provided " #| "to finalize the signup process. Please contact us if you do not receive " #| "it within a few minutes." msgid "" "We have sent an email to you for verification. Follow the link provided to " "finalize the signup process. If you do not see the verification email in " "your main inbox, check your spam folder. Please contact us if you do not " "receive the verification email within a few minutes." msgstr "" "我們剛剛寄了一封電子郵件確認信給您,請點擊郵件中的連結以完成註冊流程。若您在" "數分鐘內尚無法收到郵件,請與我們聯絡。" #: templates/account/verified_email_required.html:13 msgid "" "This part of the site requires us to verify that\n" "you are who you claim to be. For this purpose, we require that you\n" "verify ownership of your email address. " msgstr "" "此網站的此部分要求我們驗證你的身份。\n" "為此,\n" "我們要求你驗證你的電子郵件地址的所有權。 " #: templates/account/verified_email_required.html:18 #, fuzzy #| msgid "" #| "We have sent an e-mail to you for\n" #| "verification. Please click on the link inside this e-mail. Please\n" #| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" "verification. Please click on the link inside that email. If you do not see " "the verification email in your main inbox, check your spam folder. " "Otherwise\n" "contact us if you do not receive it within a few minutes." msgstr "" "我們剛剛寄了一封電子郵件確認信給您,\n" "請點擊郵件中的連結。您在數分鐘內尚無法收到郵件,請與我們聯絡。" #: templates/account/verified_email_required.html:23 #, fuzzy, python-format #| msgid "" #| "Note: you can still change " #| "your e-mail address." msgid "" "Note: you can still change your " "email address." msgstr "" "注意: 您仍能修改您的電子郵件地址 " "." #: templates/allauth/layouts/base.html:18 msgid "Messages:" msgstr "" #: templates/allauth/layouts/base.html:25 msgid "Menu:" msgstr "" #: templates/allauth/layouts/base.html:43 #: templates/socialaccount/connections.html:5 #: templates/socialaccount/connections.html:9 msgid "Account Connections" msgstr "帳號連結" #: templates/allauth/layouts/base.html:49 templates/mfa/authenticate.html:10 #: templates/mfa/index.html:5 templates/mfa/index.html:9 msgid "Two-Factor Authentication" msgstr "" #: templates/allauth/layouts/base.html:55 #: templates/usersessions/usersession_list.html:6 #: templates/usersessions/usersession_list.html:10 msgid "Sessions" msgstr "" #: templates/mfa/authenticate.html:13 msgid "" "Your account is protected by two-factor authentication. Please enter an " "authenticator code:" msgstr "" #: templates/mfa/email/recovery_codes_generated_message.txt:4 msgid "" "A new set of Two-Factor Authentication recovery codes has been generated." msgstr "" #: templates/mfa/email/recovery_codes_generated_subject.txt:3 msgid "New Recovery Codes Generated" msgstr "" #: templates/mfa/email/totp_activated_message.txt:4 #: templates/mfa/messages/totp_activated.txt:2 msgid "Authenticator app activated." msgstr "" #: templates/mfa/email/totp_activated_subject.txt:3 msgid "Authenticator App Activated" msgstr "" #: templates/mfa/email/totp_deactivated_message.txt:4 #: templates/mfa/messages/totp_deactivated.txt:2 msgid "Authenticator app deactivated." msgstr "" #: templates/mfa/email/totp_deactivated_subject.txt:3 msgid "Authenticator App Deactivated" msgstr "" #: templates/mfa/email/webauthn_added_message.txt:4 msgid "A new security key has been added." msgstr "" #: templates/mfa/email/webauthn_added_subject.txt:3 msgid "Security Key Added" msgstr "" #: templates/mfa/email/webauthn_removed_message.txt:4 #, fuzzy #| msgid "Your password has been deleted." msgid "A security key has been removed." msgstr "您的密码已被删除。" #: templates/mfa/email/webauthn_removed_subject.txt:3 msgid "Security Key Removed" msgstr "" #: templates/mfa/index.html:14 templates/mfa/totp/base.html:4 msgid "Authenticator App" msgstr "" #: templates/mfa/index.html:19 msgid "Authentication using an authenticator app is active." msgstr "" #: templates/mfa/index.html:23 msgid "An authenticator app is not active." msgstr "" #: templates/mfa/index.html:32 templates/mfa/totp/deactivate_form.html:24 msgid "Deactivate" msgstr "" #: templates/mfa/index.html:36 templates/mfa/totp/activate_form.html:32 msgid "Activate" msgstr "" #: templates/mfa/index.html:45 templates/mfa/webauthn/authenticator_list.html:8 #: templates/mfa/webauthn/base.html:4 msgid "Security Keys" msgstr "" #: templates/mfa/index.html:50 #, python-format msgid "You have added %(count)s security key." msgid_plural "You have added %(count)s security keys." msgstr[0] "" #: templates/mfa/index.html:54 #: templates/mfa/webauthn/authenticator_list.html:12 msgid "No security keys have been added." msgstr "" #: templates/mfa/index.html:62 msgid "Manage" msgstr "" #: templates/mfa/index.html:67 templates/mfa/webauthn/add_form.html:18 #: templates/mfa/webauthn/authenticator_list.html:70 #, fuzzy #| msgid "add" msgid "Add" msgstr "Voeg toe" #: templates/mfa/index.html:77 templates/mfa/recovery_codes/base.html:4 #: templates/mfa/recovery_codes/generate.html:6 #: templates/mfa/recovery_codes/index.html:6 msgid "Recovery Codes" msgstr "" #: templates/mfa/index.html:82 templates/mfa/recovery_codes/index.html:9 #, python-format msgid "" "There is %(unused_count)s out of %(total_count)s recovery codes available." msgid_plural "" "There are %(unused_count)s out of %(total_count)s recovery codes available." msgstr[0] "" #: templates/mfa/index.html:86 msgid "No recovery codes set up." msgstr "" #: templates/mfa/index.html:96 msgid "View" msgstr "" #: templates/mfa/index.html:102 msgid "Download" msgstr "" #: templates/mfa/index.html:110 templates/mfa/recovery_codes/generate.html:29 msgid "Generate" msgstr "" #: templates/mfa/messages/recovery_codes_generated.txt:2 msgid "A new set of recovery codes has been generated." msgstr "" #: templates/mfa/messages/webauthn_added.txt:2 msgid "Security key added." msgstr "" #: templates/mfa/messages/webauthn_removed.txt:2 msgid "Security key removed." msgstr "" #: templates/mfa/reauthenticate.html:6 msgid "Enter an authenticator code:" msgstr "" #: templates/mfa/recovery_codes/generate.html:9 msgid "You are about to generate a new set of recovery codes for your account." msgstr "" #: templates/mfa/recovery_codes/generate.html:11 msgid "This action will invalidate your existing codes." msgstr "" #: templates/mfa/recovery_codes/generate.html:13 msgid "Are you sure?" msgstr "" #: templates/mfa/recovery_codes/index.html:13 msgid "Unused codes" msgstr "" #: templates/mfa/recovery_codes/index.html:25 msgid "Download codes" msgstr "" #: templates/mfa/recovery_codes/index.html:30 msgid "Generate new codes" msgstr "" #: templates/mfa/totp/activate_form.html:4 #: templates/mfa/totp/activate_form.html:8 msgid "Activate Authenticator App" msgstr "" #: templates/mfa/totp/activate_form.html:11 msgid "" "To protect your account with two-factor authentication, scan the QR code " "below with your authenticator app. Then, input the verification code " "generated by the app below." msgstr "" #: templates/mfa/totp/activate_form.html:21 msgid "Authenticator secret" msgstr "" #: templates/mfa/totp/activate_form.html:24 msgid "" "You can store this secret and use it to reinstall your authenticator app at " "a later time." msgstr "" #: templates/mfa/totp/deactivate_form.html:5 #: templates/mfa/totp/deactivate_form.html:9 msgid "Deactivate Authenticator App" msgstr "" #: templates/mfa/totp/deactivate_form.html:12 msgid "" "You are about to deactivate authenticator app based authentication. Are you " "sure?" msgstr "" #: templates/mfa/webauthn/add_form.html:7 #, fuzzy #| msgid "secret key" msgid "Add Security Key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_confirm_delete.html:6 #, fuzzy #| msgid "secret key" msgid "Remove Security Key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_confirm_delete.html:9 #, fuzzy #| msgid "Are you sure you want to sign out?" msgid "Are you sure you want to remove this security key?" msgstr "您確定要登出嗎?" #: templates/mfa/webauthn/authenticator_list.html:21 msgid "Usage" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:33 msgid "Passkey" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:37 #, fuzzy #| msgid "secret key" msgid "Security key" msgstr "secret key" #: templates/mfa/webauthn/authenticator_list.html:40 msgid "This key does not indicate whether it is a passkey." msgstr "" #: templates/mfa/webauthn/authenticator_list.html:41 #, fuzzy #| msgid "Unverified" msgid "Unspecified" msgstr "未驗證" #: templates/mfa/webauthn/authenticator_list.html:46 #, python-format msgid "Added on %(created_at)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:48 #, python-format msgid "Last used %(last_used)s" msgstr "" #: templates/mfa/webauthn/authenticator_list.html:56 msgid "Edit" msgstr "" #: templates/mfa/webauthn/edit_form.html:7 #, fuzzy #| msgid "secret key" msgid "Edit Security Key" msgstr "secret key" #: templates/mfa/webauthn/edit_form.html:18 msgid "Save" msgstr "" #: templates/mfa/webauthn/signup_form.html:7 #, fuzzy #| msgid "Current Password" msgid "Create Passkey" msgstr "目前密碼" #: templates/mfa/webauthn/signup_form.html:10 msgid "" "You are about to create a passkey for your account. As you can add " "additional keys later on, you can use a descriptive name to tell the keys " "apart." msgstr "" #: templates/mfa/webauthn/signup_form.html:21 #, fuzzy #| msgid "created" msgid "Create" msgstr "已建立" #: templates/mfa/webauthn/snippets/scripts.html:2 msgid "This functionality requires JavaScript." msgstr "" #: templates/socialaccount/authentication_error.html:5 #: templates/socialaccount/authentication_error.html:9 #, fuzzy #| msgid "Social Network Login Failure" msgid "Third-Party Login Failure" msgstr "社群網路登入失敗" #: templates/socialaccount/authentication_error.html:12 #, fuzzy #| msgid "" #| "An error occurred while attempting to login via your social network " #| "account." msgid "" "An error occurred while attempting to login via your third-party account." msgstr "當嘗試用您的社群網路帳號登入時發生錯誤。" #: templates/socialaccount/connections.html:13 #, fuzzy #| msgid "" #| "You can sign in to your account using any of the following third party " #| "accounts:" msgid "" "You can sign in to your account using any of the following third-party " "accounts:" msgstr "您可以使用下列任何第三方帳號登入您的帳號:" #: templates/socialaccount/connections.html:46 #, fuzzy #| msgid "" #| "You currently have no social network accounts connected to this account." msgid "You currently have no third-party accounts connected to this account." msgstr "您目前沒有任何社群網路帳號與此帳號連結。" #: templates/socialaccount/connections.html:50 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Add a Third-Party Account" msgstr "增加一個第三方帳號" #: templates/socialaccount/email/account_connected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been connected to your account." msgstr "" #: templates/socialaccount/email/account_connected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Connected" msgstr "增加一個第三方帳號" #: templates/socialaccount/email/account_disconnected_message.txt:4 #, python-format msgid "" "A third-party account from %(provider)s has been disconnected from your " "account." msgstr "" #: templates/socialaccount/email/account_disconnected_subject.txt:3 #, fuzzy #| msgid "Add a 3rd Party Account" msgid "Third-Party Account Disconnected" msgstr "增加一個第三方帳號" #: templates/socialaccount/login.html:10 #, python-format msgid "Connect %(provider)s" msgstr "" #: templates/socialaccount/login.html:13 #, python-format msgid "You are about to connect a new third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:17 #, python-format msgid "Sign In Via %(provider)s" msgstr "" #: templates/socialaccount/login.html:20 #, python-format msgid "You are about to sign in using a third-party account from %(provider)s." msgstr "" #: templates/socialaccount/login.html:27 #: templates/socialaccount/login_redirect.html:10 msgid "Continue" msgstr "" #: templates/socialaccount/login_cancelled.html:5 #: templates/socialaccount/login_cancelled.html:9 msgid "Login Cancelled" msgstr "登入取消了" #: templates/socialaccount/login_cancelled.html:13 #, python-format msgid "" "You decided to cancel logging in to our site using one of your existing " "accounts. If this was a mistake, please proceed to sign in." msgstr "" "您決定不繼續登入這一個網站。若這是一個失誤,請由此" "重新登入。" #: templates/socialaccount/messages/account_connected.txt:2 #, fuzzy msgid "The third-party account has been connected." msgstr "社群網站帳號已連結。" #: templates/socialaccount/messages/account_disconnected.txt:2 #, fuzzy msgid "The third-party account has been disconnected." msgstr "社群網站帳號已斷開連結。" #: templates/socialaccount/signup.html:12 #, fuzzy, python-format msgid "" "You are about to use your %(provider_name)s account to login to\n" "%(site_name)s. As a final step, please complete the following form:" msgstr "" "您將使用 %(provider_name)s 這個帳號登入\n" " %(site_name)s 這個網站。最後一步,請填完下列表單:" #: templates/socialaccount/snippets/login.html:10 msgid "Or use a third-party" msgstr "" #: templates/usersessions/messages/sessions_logged_out.txt:2 msgid "Signed out of all other sessions." msgstr "" #: templates/usersessions/usersession_list.html:23 msgid "Started At" msgstr "" #: templates/usersessions/usersession_list.html:24 #, fuzzy #| msgid "Email Addresses" msgid "IP Address" msgstr "電子郵件地址" #: templates/usersessions/usersession_list.html:25 msgid "Browser" msgstr "" #: templates/usersessions/usersession_list.html:27 msgid "Last seen at" msgstr "" #: templates/usersessions/usersession_list.html:47 #, fuzzy #| msgid "Current Password" msgid "Current" msgstr "目前密碼" #: templates/usersessions/usersession_list.html:60 msgid "Sign Out Other Sessions" msgstr "" #: usersessions/apps.py:9 msgid "User Sessions" msgstr "" #: usersessions/models.py:92 msgid "session key" msgstr "" #, fuzzy #~| msgid "Account Connections" #~ msgid "Account Connection" #~ msgstr "帳號連結" #~ msgid "Use security key or device" #~ msgstr "使用安全金鑰或裝置" #, python-brace-format #~ msgid "Password must be a minimum of {0} characters." #~ msgstr "密碼長度至少要有 {0} 個字元。" #, fuzzy, python-format #~| msgid "" #~| "You're receiving this e-mail because you or someone else has requested a " #~| "password for your user account at %(site_domain)s.\n" #~| "It can be safely ignored if you did not request a password reset. Click " #~| "the link below to reset your password." #~ msgid "" #~ "You are receiving this email because you or someone else has requested a\n" #~ "password for your user account. However, we do not have any record of a " #~ "user\n" #~ "with email %(email)s in our database.\n" #~ "\n" #~ "This mail can be safely ignored if you did not request a password reset.\n" #~ "\n" #~ "If it was you, you can sign up for an account using the link below." #~ msgstr "" #~ "您會收到這封信是因為您或是某人在 %(site_domain)s 這個網站上要求重設您帳號" #~ "的密碼。\n" #~ "若您沒有要求我們重設密碼,請您直接忽略這封信。若要重設您的密碼,請點擊下面" #~ "的連結。" #, fuzzy #~| msgid "The following email addresses are associated with your account:" #~ msgid "The following email address is associated with your account:" #~ msgstr "下列電子郵件已與你的帳號連結:" #, fuzzy #~| msgid "Confirm Email Address" #~ msgid "Change Email Address" #~ msgstr "確認電子郵件" #, fuzzy, python-format #~ msgid "" #~ "Please sign in with one\n" #~ "of your existing third party accounts. Or, sign up\n" #~ "for a %(site_name)s account and sign in below:" #~ msgstr "" #~ "請用您的第三方帳號登入。\n" #~ "或者%(link)s註冊%(end_link)s \n" #~ "一個 %(site_name)s帳號後登入:" #~ msgid "or" #~ msgstr "或" #~ msgid "change password" #~ msgstr "修改密碼" #~ msgid "OpenID Sign In" #~ msgstr "OpenID 登入" #~ msgid "This email address is already associated with another account." #~ msgstr "此電子郵件已經與別的帳號連結了。" #~ msgid "" #~ "We have sent you an e-mail. Please contact us if you do not receive it " #~ "within a few minutes." #~ msgstr "" #~ "我們已經寄了一封電子郵件給您,如果數分鐘內您沒有收到,請與我們聯絡。" #~ msgid "The login and/or password you specified are not correct." #~ msgstr "您提供的帳號或密碼不正確。" #~ msgid "Usernames can only contain letters, digits and @/./+/-/_." #~ msgstr "使用者名稱只能包含字母,數字及 @/./+/-/_." #~ msgid "This username is already taken. Please choose another." #~ msgstr "這個使用者名稱已經有人用了,請換一個。" #, fuzzy #~| msgid "Sign In" #~ msgid "Shopify Sign In" #~ msgstr "登入" #~ msgid "" #~ "You have confirmed that %(email)s is an " #~ "e-mail address for user %(user_display)s." #~ msgstr "" #~ "您以確認%(email)s是使用者%(user_display)s" #~ "的電子郵件地址。" #~ msgid "Thanks for using our site!" #~ msgstr "感謝您使用我們的網站!" #~ msgid "Confirmation email sent to %(email)s" #~ msgstr "确认e-mail已发往 %(email)s" #~ msgid "Delete Password" #~ msgstr "删除密码" #~ msgid "" #~ "You may delete your password since you are currently logged in using " #~ "OpenID." #~ msgstr "您当前使用OpenID登录,因此您可以删除你的密码。" #~ msgid "delete my password" #~ msgstr "删除我的密码" #~ msgid "Password Deleted" #~ msgstr "密码已删除" #~ msgid "" #~ "If you have any trouble resetting your password, contact us at %(CONTACT_EMAIL)s." #~ msgstr "" #~ "Als je problemen hebt je wachtwoord opnieuw in te stellen, neem dan " #~ "contact op met %(CONTACT_EMAIL)s." #~ msgid "OpenID" #~ msgstr "OpenID" #~ msgid "Already have an account?" #~ msgstr "Heb je al een account?" #~ msgid "Sign in" #~ msgstr "Aanmelden" #~ msgid "Language" #~ msgstr "Taal" #~ msgid "Pinax can be used in your preferred language." #~ msgstr "Deze site kan in jouw voorkeurstaal gebruikt worden." #~ msgid "Change my language" #~ msgstr "Verander mijn taal" #~ msgid "Timezone" #~ msgstr "Tijdzone" #, fuzzy #~ msgid "" #~ "You're receiving this e-mail because you requested a password reset\n" #~ "for your user account at Pinax.\n" #~ "\n" #~ "Your new password is: %(new_password)s\n" #~ "\n" #~ "Your username, in case you've forgotten: %(username)s\n" #~ "\n" #~ "You should log in as soon as possible and change your password.\n" #~ "\n" #~ "Thanks for using our site!\n" #~ msgstr "" #~ "Je ontvangt deze mail omdat er een verzoek is ingelegd om het wachtwoord\n" #~ "behorende bij je %(site_name)s account opnieuw in te stellen.\n" #~ "\n" #~ "Je nieuwe wachtwoord is: %(new_password)s\n" #~ "\n" #~ "Je gebruikersnaam, voor het geval je die vergeten bent, is: %(username)s\n" #~ "\n" #~ "Je moet zo snel mogelijk inloggen en bovenstaand wachtwoord veranderen.\n" #~ "\n" #~ "Bedankt voor het gebruik van onze site!\n" #~ msgid "If checked you will stay logged in for 3 weeks" #~ msgstr "Bij 'Onthouden' blijf je ingelogd gedurende 3 weken" #~ msgid "Timezone successfully updated." #~ msgstr "Tijdzone gewijzigd." #~ msgid "Language successfully updated." #~ msgstr "Taal gewijzigd." #~ msgid "None" #~ msgstr "Geen" #~ msgid "Log In" #~ msgstr "Inloggen" #~ msgid "Log in" #~ msgstr "Inloggen" #~ msgid "Logout" #~ msgstr "Afmelden" #~ msgid "" #~ "When you receive the new password, you should log in and change it as soon as possible." #~ msgstr "" #~ "Zodra je het nieuwe wachtwoord ontvangen hebt moet je zo snel mogelijk inloggen en het wachtwoord wijzigen." #~ msgid "You are already logged in." #~ msgstr "Je bent al ingelogd." #~ msgid "" #~ "By clicking \"Sign Up\", you are indicating that you have read and agree " #~ "to the Terms of Use and Privacy Policy." #~ msgstr "" #~ "Door te registreren geef je aan dat je de gebruiksvoorwaarden en de privacy policy gelezen hebt en ermee akkoord " #~ "gaat." #~ msgid "" #~ "If you have any trouble creating your account, contact us at %(contact_email)s." #~ msgstr "" #~ "Als je problemen hebt om een account aan te maken, neem dan contact op " #~ "met %(contact_email)s." #~ msgid "Log in »" #~ msgstr "Inloggen" django-allauth-65.0.2/allauth/mfa/000077500000000000000000000000001467545753200167155ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/__init__.py000066400000000000000000000000001467545753200210140ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/adapter.py000066400000000000000000000127671467545753200207240ustar00rootroot00000000000000from io import BytesIO from typing import Dict from urllib.parse import quote from django.utils.http import urlencode from django.utils.translation import gettext, gettext_lazy as _ from allauth import app_settings as allauth_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.utils import ( user_display, user_email, user_pk_to_url_str, user_username, ) from allauth.core import context from allauth.core.internal.adapter import BaseAdapter from allauth.mfa import app_settings from allauth.mfa.models import Authenticator from allauth.utils import import_attribute class DefaultMFAAdapter(BaseAdapter): """The adapter class allows you to override various functionality of the ``allauth.mfa`` app. To do so, point ``settings.MFA_ADAPTER`` to your own class that derives from ``DefaultMFAAdapter`` and override the behavior by altering the implementation of the methods according to your own needs. """ error_messages = { "add_email_blocked": _( "You cannot add an email address to an account protected by two-factor authentication." ), "cannot_delete_authenticator": _( "You cannot deactivate two-factor authentication." ), "cannot_generate_recovery_codes": _( "You cannot generate recovery codes without having two-factor authentication enabled." ), "incorrect_code": _("Incorrect code."), "unverified_email": _( "You cannot activate two-factor authentication until you have verified your email address." ), } "The error messages that can occur as part of MFA form handling." def get_totp_label(self, user) -> str: """Returns the label used for representing the given user in a TOTP QR code. """ return self._get_user_identifier(user) def _get_user_identifier(self, user) -> str: """Human-palatable identifier for a user account. It is intended only for display. """ label = user_email(user) if not label: label = user_username(user) if not label: label = str(user) return label def get_totp_issuer(self) -> str: """Returns the TOTP issuer name that will be contained in the TOTP QR code. """ issuer = app_settings.TOTP_ISSUER if not issuer: issuer = self._get_site_name() return issuer def build_totp_url(self, user, secret: str) -> str: label = self.get_totp_label(user) issuer = self.get_totp_issuer() params = { "secret": secret, # This is the default # "algorithm": "SHA1", "issuer": issuer, } if app_settings.TOTP_DIGITS != 6: params["digits"] = app_settings.TOTP_DIGITS if app_settings.TOTP_PERIOD != 30: params["period"] = app_settings.TOTP_PERIOD return f"otpauth://totp/{quote(label)}?{urlencode(params)}" def build_totp_svg(self, url: str) -> str: import qrcode from qrcode.image.svg import SvgPathImage img = qrcode.make(url, image_factory=SvgPathImage) buf = BytesIO() img.save(buf) return buf.getvalue().decode("utf8") def _get_site_name(self) -> str: if allauth_settings.SITES_ENABLED: from django.contrib.sites.models import Site return Site.objects.get_current(context.request).name else: return context.request.get_host() def encrypt(self, text: str) -> str: """Secrets such as the TOTP key are stored in the database. This hook can be used to encrypt those so that they are not stored in the clear in the database. """ return text def decrypt(self, encrypted_text: str) -> str: """Counter part of ``encrypt()``.""" text = encrypted_text return text def can_delete_authenticator(self, authenticator: Authenticator) -> bool: return True def send_notification_mail(self, *args, **kwargs): return get_account_adapter().send_notification_mail(*args, **kwargs) def is_mfa_enabled(self, user, types=None) -> bool: """ Returns ``True`` if (and only if) the user has 2FA enabled. """ if user.is_anonymous: return False qs = Authenticator.objects.filter(user=user) if types is not None: qs = qs.filter(type__in=types) return qs.exists() def generate_authenticator_name(self, user, type: Authenticator.Type) -> str: """ Generate a human friendly name for the key. Used to prefill the "Add key" form. """ n = Authenticator.objects.filter(user=user, type=type).count() if n == 0: return gettext("Master key") elif n == 1: return gettext("Backup key") return gettext("Key nr. {number}").format(number=n + 1) def get_public_key_credential_rp_entity(self) -> Dict[str, str]: name = self._get_site_name() return { "id": context.request.get_host().partition(":")[0], "name": name, } def get_public_key_credential_user_entity(self, user) -> dict: return { "id": user_pk_to_url_str(user).encode("utf8"), "display_name": user_display(user), "name": self._get_user_identifier(user), } def get_adapter() -> DefaultMFAAdapter: return import_attribute(app_settings.ADAPTER)() django-allauth-65.0.2/allauth/mfa/admin.py000066400000000000000000000004651467545753200203640ustar00rootroot00000000000000from django.contrib import admin from allauth.mfa.models import Authenticator @admin.register(Authenticator) class AuthenticatorAdmin(admin.ModelAdmin): raw_id_fields = ("user",) list_display = ("user", "type", "created_at", "last_used_at") list_filter = ("type", "created_at", "last_used_at") django-allauth-65.0.2/allauth/mfa/app_settings.py000066400000000000000000000044721467545753200217760ustar00rootroot00000000000000class AppSettings: def __init__(self, prefix): self.prefix = prefix def _setting(self, name, dflt): from allauth.utils import get_setting return get_setting(self.prefix + name, dflt) @property def ADAPTER(self): return self._setting("ADAPTER", "allauth.mfa.adapter.DefaultMFAAdapter") @property def FORMS(self): return self._setting("FORMS", {}) @property def RECOVERY_CODE_COUNT(self): """ The number of recovery codes. """ return self._setting("RECOVERY_CODE_COUNT", 10) @property def TOTP_PERIOD(self): """ The period that a TOTP code will be valid for, in seconds. """ return self._setting("TOTP_PERIOD", 30) @property def TOTP_DIGITS(self): """ The number of digits for TOTP codes """ return self._setting("TOTP_DIGITS", 6) @property def TOTP_ISSUER(self): """ The issuer. """ return self._setting("TOTP_ISSUER", "") @property def TOTP_INSECURE_BYPASS_CODE(self): """ Don't use this on production. Useful for development & E2E tests only. """ from django.conf import settings from django.core.exceptions import ImproperlyConfigured code = self._setting("TOTP_INSECURE_BYPASS_CODE", None) if (not settings.DEBUG) and code: raise ImproperlyConfigured( "MFA_TOTP_INSECURE_BYPASS_CODE is for testing purposes only" ) return code @property def SUPPORTED_TYPES(self): dflt = ["recovery_codes", "totp"] return self._setting("SUPPORTED_TYPES", dflt) @property def WEBAUTHN_ALLOW_INSECURE_ORIGIN(self): return self._setting("WEBAUTHN_ALLOW_INSECURE_ORIGIN", False) @property def PASSKEY_LOGIN_ENABLED(self) -> bool: return "webauthn" in self.SUPPORTED_TYPES and self._setting( "PASSKEY_LOGIN_ENABLED", False ) @property def PASSKEY_SIGNUP_ENABLED(self) -> bool: return "webauthn" in self.SUPPORTED_TYPES and self._setting( "PASSKEY_SIGNUP_ENABLED", False ) _app_settings = AppSettings("MFA_") def __getattr__(name): # See https://peps.python.org/pep-0562/ return getattr(_app_settings, name) django-allauth-65.0.2/allauth/mfa/apps.py000066400000000000000000000010501467545753200202260ustar00rootroot00000000000000from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ from allauth import app_settings class MFAConfig(AppConfig): name = "allauth.mfa" verbose_name = _("MFA") default_auto_field = ( app_settings.DEFAULT_AUTO_FIELD or "django.db.models.BigAutoField" ) def ready(self): from allauth.account import signals as account_signals from allauth.mfa import checks # noqa from allauth.mfa import signals account_signals._add_email.connect(signals.on_add_email) django-allauth-65.0.2/allauth/mfa/base/000077500000000000000000000000001467545753200176275ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/base/__init__.py000066400000000000000000000000001467545753200217260ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/base/forms.py000066400000000000000000000026411467545753200213320ustar00rootroot00000000000000from django import forms from django.utils.translation import gettext_lazy as _ from allauth.core import context from allauth.mfa.adapter import get_adapter from allauth.mfa.base.internal.flows import ( check_rate_limit, post_authentication, ) from allauth.mfa.models import Authenticator class BaseAuthenticateForm(forms.Form): code = forms.CharField( label=_("Code"), widget=forms.TextInput( attrs={"placeholder": _("Code"), "autocomplete": "one-time-code"}, ), ) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) def clean_code(self): clear_rl = check_rate_limit(self.user) code = self.cleaned_data["code"] for auth in Authenticator.objects.filter(user=self.user).exclude( # WebAuthn cannot validate manual codes. type=Authenticator.Type.WEBAUTHN ): if auth.wrap().validate_code(code): self.authenticator = auth clear_rl() return code raise get_adapter().validation_error("incorrect_code") class AuthenticateForm(BaseAuthenticateForm): def save(self): post_authentication(context.request, self.authenticator) class ReauthenticateForm(BaseAuthenticateForm): def save(self): post_authentication(context.request, self.authenticator, reauthenticated=True) django-allauth-65.0.2/allauth/mfa/base/internal/000077500000000000000000000000001467545753200214435ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/base/internal/__init__.py000066400000000000000000000000001467545753200235420ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/base/internal/flows.py000066400000000000000000000035161467545753200231540ustar00rootroot00000000000000from typing import Callable, Optional from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal.flows.login import record_authentication from allauth.core import context, ratelimit from allauth.mfa import signals from allauth.mfa.models import Authenticator def delete_dangling_recovery_codes(user) -> Optional[Authenticator]: deleted_authenticator = None qs = Authenticator.objects.filter(user=user) if not qs.exclude(type=Authenticator.Type.RECOVERY_CODES).exists(): deleted_authenticator = qs.first() qs.delete() return deleted_authenticator def delete_and_cleanup(request, authenticator) -> None: authenticator.delete() rc_auth = delete_dangling_recovery_codes(authenticator.user) for auth in [authenticator, rc_auth]: if auth: signals.authenticator_removed.send( sender=Authenticator, request=request, user=request.user, authenticator=auth, ) def post_authentication( request, authenticator: Authenticator, reauthenticated: bool = False, passwordless: bool = False, ) -> None: authenticator.record_usage() extra_data = { "id": authenticator.pk, "type": authenticator.type, } if reauthenticated: extra_data["reauthenticated"] = True if passwordless: extra_data["passwordless"] = True record_authentication(request, "mfa", **extra_data) def check_rate_limit(user) -> Callable[[], None]: key = f"mfa-auth-user-{str(user.pk)}" if not ratelimit.consume( context.request, action="login_failed", key=key, ): raise get_account_adapter().validation_error("too_many_login_attempts") return lambda: ratelimit.clear(context.request, action="login_failed", key=key) django-allauth-65.0.2/allauth/mfa/base/tests/000077500000000000000000000000001467545753200207715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/base/tests/__init__.py000066400000000000000000000000001467545753200230700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/base/tests/test_views.py000066400000000000000000000042351467545753200235430ustar00rootroot00000000000000from unittest.mock import ANY from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.mfa.models import Authenticator def test_reauthentication(auth_client, user_with_recovery_codes): resp = auth_client.get(reverse("mfa_view_recovery_codes")) assert resp.status_code == 302 assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.get(reverse("mfa_reauthenticate")) assertTemplateUsed(resp, "mfa/reauthenticate.html") authenticator = Authenticator.objects.get( user=user_with_recovery_codes, type=Authenticator.Type.RECOVERY_CODES ) unused_code = authenticator.wrap().get_unused_codes()[0] resp = auth_client.post(reverse("mfa_reauthenticate"), data={"code": unused_code}) assert resp.status_code == 302 resp = auth_client.get(reverse("mfa_view_recovery_codes")) assert resp.status_code == 200 assertTemplateUsed(resp, "mfa/recovery_codes/index.html") methods = auth_client.session[AUTHENTICATION_METHODS_SESSION_KEY] assert methods[-1] == { "method": "mfa", "type": "recovery_codes", "id": authenticator.pk, "at": ANY, "reauthenticated": True, } @pytest.mark.parametrize( "url_name", ( "mfa_activate_totp", "mfa_index", "mfa_deactivate_totp", ), ) def test_login_required_views(client, url_name): resp = client.get(reverse(url_name)) assert resp.status_code == 302 assert resp["location"].startswith(reverse("account_login")) def test_index(auth_client, user_with_totp): resp = auth_client.get(reverse("mfa_index")) assert "authenticators" in resp.context def test_add_email_not_allowed(auth_client, user_with_totp): resp = auth_client.post( reverse("account_email"), {"action_add": "", "email": "change-to@this.org"}, ) assert resp.status_code == 200 assert resp.context["form"].errors == { "email": [ "You cannot add an email address to an account protected by two-factor authentication." ] } django-allauth-65.0.2/allauth/mfa/base/urls.py000066400000000000000000000005671467545753200211760ustar00rootroot00000000000000from typing import List, Union from django.urls import URLPattern, URLResolver, path from allauth.mfa.base import views urlpatterns: List[Union[URLPattern, URLResolver]] = [ path("", views.index, name="mfa_index"), path("authenticate/", views.authenticate, name="mfa_authenticate"), path("reauthenticate/", views.reauthenticate, name="mfa_reauthenticate"), ] django-allauth-65.0.2/allauth/mfa/base/views.py000066400000000000000000000126121467545753200213400ustar00rootroot00000000000000from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect from django.urls import reverse from django.utils.decorators import method_decorator from django.views.generic import TemplateView from allauth.account import app_settings as account_settings from allauth.account.internal.decorators import login_stage_required from allauth.account.views import BaseReauthenticateView from allauth.mfa import app_settings from allauth.mfa.base.forms import AuthenticateForm, ReauthenticateForm from allauth.mfa.models import Authenticator from allauth.mfa.stages import AuthenticateStage from allauth.mfa.utils import is_mfa_enabled from allauth.mfa.webauthn.forms import AuthenticateWebAuthnForm from allauth.mfa.webauthn.internal.flows import auth as webauthn_auth from allauth.utils import get_form_class @method_decorator( login_stage_required(stage=AuthenticateStage.key, redirect_urlname="account_login"), name="dispatch", ) class AuthenticateView(TemplateView): form_class = AuthenticateForm webauthn_form_class = AuthenticateWebAuthnForm template_name = "mfa/authenticate." + account_settings.TEMPLATE_EXTENSION def dispatch(self, request, *args, **kwargs): self.stage = request._login_stage if not is_mfa_enabled( self.stage.login.user, [Authenticator.Type.TOTP, Authenticator.Type.WEBAUTHN], ): return HttpResponseRedirect(reverse("account_login")) self.form = self._build_forms() return super().dispatch(request, *args, **kwargs) def post(self, request, *args, **kwargs): if self.form.is_valid(): return self.form_valid(self.form) else: return self.form_invalid(self.form) def _build_forms(self): posted_form = None AuthenticateFormClass = self.get_form_class() AuthenticateWebAuthnFormClass = self.get_webauthn_form_class() user = self.stage.login.user support_webauthn = "webauthn" in app_settings.SUPPORTED_TYPES if self.request.method == "POST": if "code" in self.request.POST: posted_form = self.auth_form = AuthenticateFormClass( user=user, data=self.request.POST ) self.webauthn_form = ( AuthenticateWebAuthnFormClass(user=user) if support_webauthn else None ) else: self.auth_form = ( AuthenticateFormClass(user=user) if support_webauthn else None ) posted_form = self.webauthn_form = AuthenticateWebAuthnFormClass( user=user, data=self.request.POST ) else: self.auth_form = AuthenticateFormClass(user=user) self.webauthn_form = ( AuthenticateWebAuthnFormClass(user=user) if support_webauthn else None ) return posted_form def get_form_class(self): return get_form_class(app_settings.FORMS, "authenticate", self.form_class) def get_webauthn_form_class(self): return get_form_class( app_settings.FORMS, "authenticate_webauthn", self.webauthn_form_class ) def form_valid(self, form): form.save() return self.stage.exit() def form_invalid(self, form): return super().get(self.request) def get_context_data(self, **kwargs): ret = super().get_context_data() ret.update( { "form": self.auth_form, "MFA_SUPPORTED_TYPES": app_settings.SUPPORTED_TYPES, } ) if self.webauthn_form: request_options = webauthn_auth.begin_authentication(self.stage.login.user) ret.update( { "webauthn_form": self.webauthn_form, "js_data": {"request_options": request_options}, } ) return ret authenticate = AuthenticateView.as_view() @method_decorator(login_required, name="dispatch") class ReauthenticateView(BaseReauthenticateView): form_class = ReauthenticateForm template_name = "mfa/reauthenticate." + account_settings.TEMPLATE_EXTENSION def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request.user return ret def get_form_class(self): return get_form_class(app_settings.FORMS, "reauthenticate", self.form_class) def form_valid(self, form): form.save() return super().form_valid(form) reauthenticate = ReauthenticateView.as_view() @method_decorator(login_required, name="dispatch") class IndexView(TemplateView): template_name = "mfa/index." + account_settings.TEMPLATE_EXTENSION def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) authenticators = {} for auth in Authenticator.objects.filter(user=self.request.user): if auth.type == Authenticator.Type.WEBAUTHN: auths = authenticators.setdefault(auth.type, []) auths.append(auth.wrap()) else: authenticators[auth.type] = auth.wrap() ret["authenticators"] = authenticators ret["MFA_SUPPORTED_TYPES"] = app_settings.SUPPORTED_TYPES ret["is_mfa_enabled"] = is_mfa_enabled(self.request.user) return ret index = IndexView.as_view() django-allauth-65.0.2/allauth/mfa/checks.py000066400000000000000000000030011467545753200205210ustar00rootroot00000000000000from django.core.checks import Critical, register @register() def settings_check(app_configs, **kwargs): from allauth.account import app_settings as account_settings from allauth.mfa import app_settings from allauth.mfa.models import Authenticator ret = [] if app_settings.PASSKEY_SIGNUP_ENABLED: if Authenticator.Type.WEBAUTHN not in app_settings.SUPPORTED_TYPES: ret.append( Critical( msg="MFA_PASSKEY_SIGNUP_ENABLED requires MFA_SUPPORTED_TYPES to include 'webauthn'" ) ) if not account_settings.EMAIL_VERIFICATION_BY_CODE_ENABLED: # The fact that a signup is passkey based is stored in the session, # which gets lost when using link based verification. ret.append( Critical( msg="MFA_PASSKEY_SIGNUP_ENABLED requires ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED" ) ) if not account_settings.EMAIL_REQUIRED: ret.append( Critical( msg="MFA_PASSKEY_SIGNUP_ENABLED requires ACCOUNT_EMAIL_REQUIRED" ) ) if ( account_settings.EMAIL_VERIFICATION != account_settings.EmailVerificationMethod.MANDATORY ): ret.append( Critical( msg="MFA_PASSKEY_SIGNUP_ENABLED requires ACCOUNT_EMAIL_VERIFICIATION = 'mandatory'" ) ) return ret django-allauth-65.0.2/allauth/mfa/internal/000077500000000000000000000000001467545753200205315ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/internal/__init__.py000066400000000000000000000000001467545753200226300ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/internal/flows/000077500000000000000000000000001467545753200216635ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/internal/flows/__init__.py000066400000000000000000000000001467545753200237620ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/internal/flows/add.py000066400000000000000000000030741467545753200227710ustar00rootroot00000000000000from functools import wraps from django.contrib import messages from django.core.exceptions import ValidationError from django.http import HttpResponseRedirect from django.urls import reverse from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.models import EmailAddress from allauth.mfa.adapter import get_adapter def validate_can_add_authenticator(user): """ If we would allow users to enable 2FA with unverified email address, that would allow for an attacker to signup, not verify and prevent the real owner of the account from ever regaining access. """ email_verified = not EmailAddress.objects.filter(user=user, verified=False).exists() if not email_verified: raise get_adapter().validation_error("unverified_email") def redirect_if_add_not_allowed(function=None): def decorator(view_func): @wraps(view_func) def _wrapper_view(request, *args, **kwargs): if request.user.is_authenticated: # allow for this to go before reauth try: validate_can_add_authenticator(request.user) except ValidationError as e: for message in e.messages: adapter = get_account_adapter() adapter.add_message(request, messages.ERROR, message=message) return HttpResponseRedirect(reverse("mfa_index")) return view_func(request, *args, **kwargs) return _wrapper_view if function: return decorator(function) return decorator django-allauth-65.0.2/allauth/mfa/migrations/000077500000000000000000000000001467545753200210715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/migrations/0001_initial.py000066400000000000000000000027161467545753200235420ustar00rootroot00000000000000# Generated by Django 3.2.20 on 2023-08-19 14:43 import django.db.models.deletion from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name="Authenticator", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "type", models.CharField( choices=[ ("recovery_codes", "Recovery codes"), ("totp", "TOTP Authenticator"), ], max_length=20, ), ), ("data", models.JSONField()), ( "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), ], options={ "unique_together": {("user", "type")}, }, ), ] django-allauth-65.0.2/allauth/mfa/migrations/0002_authenticator_timestamps.py000066400000000000000000000011251467545753200272230ustar00rootroot00000000000000# Generated by Django 3.2.22 on 2023-11-06 12:04 import django.utils.timezone from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("mfa", "0001_initial"), ] operations = [ migrations.AddField( model_name="authenticator", name="created_at", field=models.DateTimeField(default=django.utils.timezone.now), ), migrations.AddField( model_name="authenticator", name="last_used_at", field=models.DateTimeField(null=True), ), ] django-allauth-65.0.2/allauth/mfa/migrations/0003_authenticator_type_uniq.py000066400000000000000000000020461467545753200270560ustar00rootroot00000000000000# Generated by Django 3.2.20 on 2023-09-27 11:59 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("mfa", "0002_authenticator_timestamps"), ] operations = [ migrations.AlterField( model_name="authenticator", name="type", field=models.CharField( choices=[ ("recovery_codes", "Recovery codes"), ("totp", "TOTP Authenticator"), ("webauthn", "WebAuthn"), ], max_length=20, ), ), migrations.AlterUniqueTogether( name="authenticator", unique_together=set(), ), migrations.AddConstraint( model_name="authenticator", constraint=models.UniqueConstraint( condition=models.Q(("type__in", ("totp", "recovery_codes"))), fields=("user", "type"), name="unique_authenticator_type", ), ), ] django-allauth-65.0.2/allauth/mfa/migrations/__init__.py000066400000000000000000000000001467545753200231700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/models.py000066400000000000000000000041161467545753200205540ustar00rootroot00000000000000from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import models from django.db.models import Q from django.db.models.constraints import UniqueConstraint from django.utils import timezone from django.utils.translation import gettext_lazy as _ from allauth import app_settings as allauth_settings if not allauth_settings.MFA_ENABLED: raise ImproperlyConfigured( "allauth.mfa not installed, yet its models are imported." ) class AuthenticatorManager(models.Manager): pass class Authenticator(models.Model): class Type(models.TextChoices): RECOVERY_CODES = "recovery_codes", _("Recovery codes") TOTP = "totp", _("TOTP Authenticator") WEBAUTHN = "webauthn", _("WebAuthn") objects = AuthenticatorManager() user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) type = models.CharField(max_length=20, choices=Type.choices) data = models.JSONField() created_at = models.DateTimeField(default=timezone.now) last_used_at = models.DateTimeField(null=True) class Meta: constraints = [ UniqueConstraint( fields=["user", "type"], name="unique_authenticator_type", condition=Q( type__in=( "totp", "recovery_codes", ) ), ) ] def __str__(self): if self.type == self.Type.WEBAUTHN: return self.wrap().name return self.get_type_display() def wrap(self): from allauth.mfa.recovery_codes.internal.auth import RecoveryCodes from allauth.mfa.totp.internal.auth import TOTP from allauth.mfa.webauthn.internal.auth import WebAuthn return { self.Type.TOTP: TOTP, self.Type.RECOVERY_CODES: RecoveryCodes, self.Type.WEBAUTHN: WebAuthn, }[self.type](self) def record_usage(self) -> None: self.last_used_at = timezone.now() self.save(update_fields=["last_used_at"]) django-allauth-65.0.2/allauth/mfa/recovery_codes/000077500000000000000000000000001467545753200217305ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/recovery_codes/__init__.py000066400000000000000000000000001467545753200240270ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/recovery_codes/forms.py000066400000000000000000000010161467545753200234260ustar00rootroot00000000000000from django import forms from allauth.mfa.adapter import get_adapter from allauth.mfa.recovery_codes.internal import flows class GenerateRecoveryCodesForm(forms.Form): def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) def clean(self): cleaned_data = super().clean() if not flows.can_generate_recovery_codes(self.user): raise get_adapter().validation_error("cannot_generate_recovery_codes") return cleaned_data django-allauth-65.0.2/allauth/mfa/recovery_codes/internal/000077500000000000000000000000001467545753200235445ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/recovery_codes/internal/__init__.py000066400000000000000000000000001467545753200256430ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/recovery_codes/internal/auth.py000066400000000000000000000066731467545753200250730ustar00rootroot00000000000000import binascii import hmac import os import struct from hashlib import sha1 from typing import List, Optional from allauth.mfa import app_settings from allauth.mfa.models import Authenticator from allauth.mfa.utils import decrypt, encrypt class RecoveryCodes: def __init__(self, instance: Authenticator) -> None: self.instance = instance @classmethod def activate(cls, user) -> "RecoveryCodes": instance = Authenticator.objects.filter( user=user, type=Authenticator.Type.RECOVERY_CODES ).first() if instance: return cls(instance) instance = Authenticator( user=user, type=Authenticator.Type.RECOVERY_CODES, data={ "seed": encrypt(cls.generate_seed()), "used_mask": 0, }, ) instance.save() return cls(instance) @classmethod def generate_seed(self) -> str: key = binascii.hexlify(os.urandom(20)).decode("ascii") return key def _get_migrated_codes(self) -> Optional[List[str]]: codes = self.instance.data.get("migrated_codes") if codes is not None: return [decrypt(code) for code in codes] return None def generate_codes(self) -> List[str]: migrated_codes = self._get_migrated_codes() if migrated_codes is not None: return migrated_codes ret = [] seed = decrypt(self.instance.data["seed"]) h = hmac.new(key=seed.encode("ascii"), msg=None, digestmod=sha1) for i in range(app_settings.RECOVERY_CODE_COUNT): h.update((f"{i:3},").encode("utf-8")) value = struct.unpack(">I", h.digest()[:4])[0] value %= 10**8 fmt_value = f"{value:08}" ret.append(fmt_value) return ret def _is_code_used(self, i: int) -> bool: used_mask = self.instance.data["used_mask"] return bool(used_mask & (1 << i)) def _mark_code_used(self, i: int) -> None: used_mask = self.instance.data["used_mask"] used_mask |= 1 << i self.instance.data["used_mask"] = used_mask self.instance.save() def get_unused_codes(self) -> List[str]: migrated_codes = self._get_migrated_codes() if migrated_codes is not None: return migrated_codes ret = [] for i, code in enumerate(self.generate_codes()): if self._is_code_used(i): continue ret.append(code) return ret def _validate_migrated_code(self, code: str) -> Optional[bool]: migrated_codes = self._get_migrated_codes() if migrated_codes is None: return None try: idx = migrated_codes.index(code) except ValueError: return False else: migrated_codes = self.instance.data["migrated_codes"] assert isinstance(migrated_codes, list) migrated_codes.pop(idx) self.instance.data["migrated_codes"] = migrated_codes self.instance.save() return True def validate_code(self, code: str) -> bool: ret = self._validate_migrated_code(code) if ret is not None: return ret for i, c in enumerate(self.generate_codes()): if self._is_code_used(i): continue if code == c: self._mark_code_used(i) return True return False django-allauth-65.0.2/allauth/mfa/recovery_codes/internal/flows.py000066400000000000000000000050301467545753200252460ustar00rootroot00000000000000from typing import Optional from django.contrib import messages from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal.flows.reauthentication import ( raise_if_reauthentication_required, ) from allauth.mfa import app_settings, signals from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.internal.auth import RecoveryCodes def can_generate_recovery_codes(user) -> bool: return ( Authenticator.objects.filter(user=user) .exclude(type=Authenticator.Type.RECOVERY_CODES) .exists() ) def generate_recovery_codes(request) -> Authenticator: raise_if_reauthentication_required(request) Authenticator.objects.filter( user=request.user, type=Authenticator.Type.RECOVERY_CODES ).delete() rc_auth = RecoveryCodes.activate(request.user) authenticator = rc_auth.instance adapter = get_account_adapter(request) adapter.add_message( request, messages.SUCCESS, "mfa/messages/recovery_codes_generated.txt" ) signals.authenticator_reset.send( sender=Authenticator, request=request, user=request.user, authenticator=authenticator, ) adapter.send_notification_mail("mfa/email/recovery_codes_generated", request.user) return authenticator def view_recovery_codes(request) -> Optional[Authenticator]: authenticator = Authenticator.objects.filter( user=request.user, type=Authenticator.Type.RECOVERY_CODES, ).first() if not authenticator: return None raise_if_reauthentication_required(request) return authenticator def auto_generate_recovery_codes(request) -> Optional[Authenticator]: """Automatically (implicitly) setup recovery codes when another authenticator is setup for. As this is part of setting up another (primary) authenticator, we do not send a notification email in this case. """ if Authenticator.Type.RECOVERY_CODES not in app_settings.SUPPORTED_TYPES: return None has_rc = Authenticator.objects.filter( user=request.user, type=Authenticator.Type.RECOVERY_CODES ).exists() if has_rc: return None rc = RecoveryCodes.activate(request.user) signals.authenticator_added.send( sender=Authenticator, request=request, user=request.user, authenticator=rc.instance, ) adapter = get_account_adapter(request) adapter.add_message( request, messages.SUCCESS, "mfa/messages/recovery_codes_generated.txt" ) return rc.instance django-allauth-65.0.2/allauth/mfa/recovery_codes/tests/000077500000000000000000000000001467545753200230725ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/recovery_codes/tests/__init__.py000066400000000000000000000000001467545753200251710ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/recovery_codes/tests/test_auth.py000066400000000000000000000024111467545753200254420ustar00rootroot00000000000000from allauth.mfa import app_settings from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.internal.auth import RecoveryCodes def test_flow(user): rc = RecoveryCodes.activate(user) codes = rc.generate_codes() assert len(set(codes)) == app_settings.RECOVERY_CODE_COUNT for i in range(app_settings.RECOVERY_CODE_COUNT): assert not rc._is_code_used(i) idx = 3 assert rc.validate_code(codes[idx]) for i in range(app_settings.RECOVERY_CODE_COUNT): assert rc._is_code_used(i) == (i == idx) assert not rc.validate_code(codes[idx]) unused_codes = rc.get_unused_codes() assert codes[idx] not in unused_codes assert len(unused_codes) == app_settings.RECOVERY_CODE_COUNT - 1 def test_migrated_codes(db, user): auth = Authenticator(user=user, data={"migrated_codes": ["abc", "def"]}) rc = RecoveryCodes(auth) assert rc.generate_codes() == ["abc", "def"] assert rc.get_unused_codes() == ["abc", "def"] assert not rc.validate_code("bad") assert rc.validate_code("abc") auth.refresh_from_db() rc = RecoveryCodes(auth) assert rc.generate_codes() == ["def"] assert rc.get_unused_codes() == ["def"] rc.validate_code("def") assert rc.instance.data["migrated_codes"] == [] django-allauth-65.0.2/allauth/mfa/recovery_codes/tests/test_views.py000066400000000000000000000076151467545753200256510ustar00rootroot00000000000000from unittest.mock import ANY from django.conf import settings from django.urls import reverse from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.mfa import app_settings from allauth.mfa.adapter import get_adapter from allauth.mfa.models import Authenticator def test_generate_recovery_codes_require_other_authenticator( auth_client, user, settings, reauthentication_bypass ): with reauthentication_bypass(): resp = auth_client.post(reverse("mfa_generate_recovery_codes")) assert resp.context["form"].errors == { "__all__": [ "You cannot generate recovery codes without having two-factor authentication enabled." ] } assert not Authenticator.objects.filter(user=user).exists() def test_download_recovery_codes(auth_client, user_with_recovery_codes, user_password): resp = auth_client.get(reverse("mfa_download_recovery_codes")) assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.post(resp["location"], {"password": user_password}) assert resp.status_code == 302 resp = auth_client.get(resp["location"]) assert resp["content-disposition"] == 'attachment; filename="recovery-codes.txt"' def test_view_recovery_codes(auth_client, user_with_recovery_codes, user_password): resp = auth_client.get(reverse("mfa_view_recovery_codes")) assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.post(resp["location"], {"password": user_password}) assert resp.status_code == 302 resp = auth_client.get(resp["location"]) assert len(resp.context["unused_codes"]) == app_settings.RECOVERY_CODE_COUNT def test_generate_recovery_codes( auth_client, user_with_recovery_codes, user_password, settings, mailoutbox ): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True rc = Authenticator.objects.get( user=user_with_recovery_codes, type=Authenticator.Type.RECOVERY_CODES ).wrap() prev_code = rc.get_unused_codes()[0] resp = auth_client.get(reverse("mfa_generate_recovery_codes")) assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.post(resp["location"], {"password": user_password}) assert resp.status_code == 302 resp = auth_client.post(resp["location"]) assert resp["location"] == reverse("mfa_view_recovery_codes") rc = Authenticator.objects.get( user=user_with_recovery_codes, type=Authenticator.Type.RECOVERY_CODES ).wrap() assert not rc.validate_code(prev_code) assert len(mailoutbox) == 1 assert "New Recovery Codes Generated" in mailoutbox[0].subject assert "A new set of" in mailoutbox[0].body def test_recovery_codes_login( client, user_with_totp, user_with_recovery_codes, user_password ): resp = client.post( reverse("account_login"), {"login": user_with_totp.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_authenticate") resp = client.get(reverse("mfa_authenticate")) assert resp.context["request"].user.is_anonymous resp = client.post(reverse("mfa_authenticate"), {"code": "123"}) assert resp.context["form"].errors == { "code": [get_adapter().error_messages["incorrect_code"]] } rc = Authenticator.objects.get( user=user_with_recovery_codes, type=Authenticator.Type.RECOVERY_CODES ) resp = client.post( reverse("mfa_authenticate"), {"code": rc.wrap().get_unused_codes()[0]}, ) assert resp.status_code == 302 assert resp["location"] == settings.LOGIN_REDIRECT_URL assert client.session[AUTHENTICATION_METHODS_SESSION_KEY] == [ {"method": "password", "at": ANY, "username": user_with_totp.username}, { "method": "mfa", "at": ANY, "id": ANY, "type": Authenticator.Type.RECOVERY_CODES, }, ] django-allauth-65.0.2/allauth/mfa/recovery_codes/urls.py000066400000000000000000000007711467545753200232740ustar00rootroot00000000000000from typing import List, Union from django.urls import URLPattern, URLResolver, path from allauth.mfa.recovery_codes import views urlpatterns: List[Union[URLPattern, URLResolver]] = [ path("", views.view_recovery_codes, name="mfa_view_recovery_codes"), path( "generate/", views.generate_recovery_codes, name="mfa_generate_recovery_codes", ), path( "download/", views.download_recovery_codes, name="mfa_download_recovery_codes", ), ] django-allauth-65.0.2/allauth/mfa/recovery_codes/views.py000066400000000000000000000067261467545753200234520ustar00rootroot00000000000000from django.contrib.auth.decorators import login_required from django.http import Http404 from django.urls import reverse_lazy from django.utils.decorators import method_decorator from django.views.generic import TemplateView from django.views.generic.edit import FormView from allauth.account import app_settings as account_settings from allauth.account.decorators import reauthentication_required from allauth.mfa import app_settings from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.forms import GenerateRecoveryCodesForm from allauth.mfa.recovery_codes.internal import flows from allauth.utils import get_form_class @method_decorator(reauthentication_required, name="dispatch") class GenerateRecoveryCodesView(FormView): form_class = GenerateRecoveryCodesForm template_name = "mfa/recovery_codes/generate." + account_settings.TEMPLATE_EXTENSION success_url = reverse_lazy("mfa_view_recovery_codes") def form_valid(self, form): flows.generate_recovery_codes(self.request) return super().form_valid(form) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) unused_codes = [] authenticator = Authenticator.objects.filter( user=self.request.user, type=Authenticator.Type.RECOVERY_CODES ).first() if authenticator: unused_codes = authenticator.wrap().get_unused_codes() ret["unused_code_count"] = len(unused_codes) return ret def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request.user return ret def get_form_class(self): return get_form_class( app_settings.FORMS, "generate_recovery_codes", self.form_class ) generate_recovery_codes = GenerateRecoveryCodesView.as_view() @method_decorator(login_required, name="dispatch") class DownloadRecoveryCodesView(TemplateView): template_name = "mfa/recovery_codes/download.txt" content_type = "text/plain" def dispatch(self, request, *args, **kwargs): self.authenticator = flows.view_recovery_codes(self.request) if not self.authenticator: raise Http404() self.unused_codes = self.authenticator.wrap().get_unused_codes() if not self.unused_codes: return Http404() return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) ret["unused_codes"] = self.unused_codes return ret def render_to_response(self, context, **response_kwargs): response = super().render_to_response(context, **response_kwargs) response["Content-Disposition"] = 'attachment; filename="recovery-codes.txt"' return response download_recovery_codes = DownloadRecoveryCodesView.as_view() @method_decorator(login_required, name="dispatch") class ViewRecoveryCodesView(TemplateView): template_name = "mfa/recovery_codes/index." + account_settings.TEMPLATE_EXTENSION def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) authenticator = flows.view_recovery_codes(self.request) if not authenticator: raise Http404() ret.update( { "unused_codes": authenticator.wrap().get_unused_codes(), "total_count": app_settings.RECOVERY_CODE_COUNT, } ) return ret view_recovery_codes = ViewRecoveryCodesView.as_view() django-allauth-65.0.2/allauth/mfa/signals.py000066400000000000000000000012541467545753200207310ustar00rootroot00000000000000from django.dispatch import Signal from allauth.mfa.adapter import get_adapter from allauth.mfa.utils import is_mfa_enabled # Emitted when an authenticator is added. # Arguments: request, user, authenticator authenticator_added = Signal() # Emitted when an authenticator is removed. # Arguments: request, user, authenticator authenticator_removed = Signal() # Emitted when an authenticator is reset (e.g. recovery codes regenerated). # Arguments: request, user, authenticator authenticator_reset = Signal() def on_add_email(sender, email, user, **kwargs): if is_mfa_enabled(user): adapter = get_adapter() raise adapter.validation_error("add_email_blocked") django-allauth-65.0.2/allauth/mfa/stages.py000066400000000000000000000016701467545753200205610ustar00rootroot00000000000000from allauth.account.stages import LoginStage from allauth.core.internal.httpkit import headed_redirect_response from allauth.mfa.models import Authenticator from allauth.mfa.utils import is_mfa_enabled from allauth.mfa.webauthn.internal.flows import did_use_passwordless_login class AuthenticateStage(LoginStage): # NOTE: Duplicated in `allauth.headless.constants.Flow.MFA_AUTHENTICATE`. key = "mfa_authenticate" urlname = "mfa_authenticate" def handle(self): response, cont = None, True if self._should_handle(self.request): response = headed_redirect_response("mfa_authenticate") return response, cont def _should_handle(self, request) -> bool: if not is_mfa_enabled( self.login.user, [Authenticator.Type.TOTP, Authenticator.Type.WEBAUTHN] ): return False if did_use_passwordless_login(request): return False return True django-allauth-65.0.2/allauth/mfa/static/000077500000000000000000000000001467545753200202045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/static/mfa/000077500000000000000000000000001467545753200207475ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/static/mfa/js/000077500000000000000000000000001467545753200213635ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/static/mfa/js/webauthn-json.js000066400000000000000000000167561467545753200245240ustar00rootroot00000000000000// https://github.com/github/webauthn-json 'use strict'; (() => { const __defProp = Object.defineProperty const __export = (target, all) => { for (const name in all) { __defProp(target, name, { get: all[name], enumerable: true }) } } const __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { const fulfilled = (value) => { try { step(generator.next(value)) } catch (e) { reject(e) } } const rejected = (value) => { try { step(generator.throw(value)) } catch (e) { reject(e) } } var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected) step((generator = generator.apply(__this, __arguments)).next()) }) } // src/webauthn-json/index.ts const webauthn_json_exports = {} __export(webauthn_json_exports, { create: () => create, get: () => get, schema: () => schema, supported: () => supported }) // src/webauthn-json/base64url.ts function base64urlToBuffer (baseurl64String) { const padding = '=='.slice(0, (4 - baseurl64String.length % 4) % 4) const base64String = baseurl64String.replace(/-/g, '+').replace(/_/g, '/') + padding const str = atob(base64String) const buffer = new ArrayBuffer(str.length) const byteView = new Uint8Array(buffer) for (let i = 0; i < str.length; i++) { byteView[i] = str.charCodeAt(i) } return buffer } function bufferToBase64url (buffer) { const byteView = new Uint8Array(buffer) let str = '' for (const charCode of byteView) { str += String.fromCharCode(charCode) } const base64String = btoa(str) const base64urlString = base64String.replace(/\+/g, '-').replace( /\//g, '_' ).replace(/=/g, '') return base64urlString } // src/webauthn-json/convert.ts const copyValue = 'copy' const convertValue = 'convert' function convert (conversionFn, schema2, input) { if (schema2 === copyValue) { return input } if (schema2 === convertValue) { return conversionFn(input) } if (schema2 instanceof Array) { return input.map((v) => convert(conversionFn, schema2[0], v)) } if (schema2 instanceof Object) { const output = {} for (const [key, schemaField] of Object.entries(schema2)) { if (schemaField.derive) { const v = schemaField.derive(input) if (v !== void 0) { input[key] = v } } if (!(key in input)) { if (schemaField.required) { throw new Error(`Missing key: ${key}`) } continue } if (input[key] == null) { output[key] = null continue } output[key] = convert( conversionFn, schemaField.schema, input[key] ) } return output } } function derived (schema2, derive) { return { required: true, schema: schema2, derive } } function required (schema2) { return { required: true, schema: schema2 } } function optional (schema2) { return { required: false, schema: schema2 } } // src/webauthn-json/basic/schema.ts const publicKeyCredentialDescriptorSchema = { type: required(copyValue), id: required(convertValue), transports: optional(copyValue) } const simplifiedExtensionsSchema = { appid: optional(copyValue), appidExclude: optional(copyValue), credProps: optional(copyValue) } const simplifiedClientExtensionResultsSchema = { appid: optional(copyValue), appidExclude: optional(copyValue), credProps: optional(copyValue) } const credentialCreationOptions = { publicKey: required({ rp: required(copyValue), user: required({ id: required(convertValue), name: required(copyValue), displayName: required(copyValue) }), challenge: required(convertValue), pubKeyCredParams: required(copyValue), timeout: optional(copyValue), excludeCredentials: optional([publicKeyCredentialDescriptorSchema]), authenticatorSelection: optional(copyValue), attestation: optional(copyValue), extensions: optional(simplifiedExtensionsSchema) }), signal: optional(copyValue) } const publicKeyCredentialWithAttestation = { type: required(copyValue), id: required(copyValue), rawId: required(convertValue), authenticatorAttachment: optional(copyValue), response: required({ clientDataJSON: required(convertValue), attestationObject: required(convertValue), transports: derived( copyValue, (response) => { let _a return ((_a = response.getTransports) == null ? void 0 : _a.call(response)) || [] } ) }), clientExtensionResults: derived( simplifiedClientExtensionResultsSchema, (pkc) => pkc.getClientExtensionResults() ) } const credentialRequestOptions = { mediation: optional(copyValue), publicKey: required({ challenge: required(convertValue), timeout: optional(copyValue), rpId: optional(copyValue), allowCredentials: optional([publicKeyCredentialDescriptorSchema]), userVerification: optional(copyValue), extensions: optional(simplifiedExtensionsSchema) }), signal: optional(copyValue) } const publicKeyCredentialWithAssertion = { type: required(copyValue), id: required(copyValue), rawId: required(convertValue), authenticatorAttachment: optional(copyValue), response: required({ clientDataJSON: required(convertValue), authenticatorData: required(convertValue), signature: required(convertValue), userHandle: required(convertValue) }), clientExtensionResults: derived( simplifiedClientExtensionResultsSchema, (pkc) => pkc.getClientExtensionResults() ) } var schema = { credentialCreationOptions, publicKeyCredentialWithAttestation, credentialRequestOptions, publicKeyCredentialWithAssertion } // src/webauthn-json/basic/api.ts function createRequestFromJSON (requestJSON) { return convert(base64urlToBuffer, credentialCreationOptions, requestJSON) } function createResponseToJSON (credential) { return convert( bufferToBase64url, publicKeyCredentialWithAttestation, credential ) } function create (requestJSON) { return __async(this, null, function * () { const credential = yield navigator.credentials.create( createRequestFromJSON(requestJSON) ) return createResponseToJSON(credential) }) } function getRequestFromJSON (requestJSON) { return convert(base64urlToBuffer, credentialRequestOptions, requestJSON) } function getResponseToJSON (credential) { return convert( bufferToBase64url, publicKeyCredentialWithAssertion, credential ) } function get (requestJSON) { return __async(this, null, function * () { const credential = yield navigator.credentials.get( getRequestFromJSON(requestJSON) ) return getResponseToJSON(credential) }) } // src/webauthn-json/basic/supported.ts function supported () { return !!(navigator.credentials && navigator.credentials.create && navigator.credentials.get && window.PublicKeyCredential) } // src/webauthn-json/browser-global.ts globalThis.webauthnJSON = webauthn_json_exports })() // # sourceMappingURL=webauthn-json.browser-global.js.map django-allauth-65.0.2/allauth/mfa/static/mfa/js/webauthn.js000066400000000000000000000064261467545753200235460ustar00rootroot00000000000000(function () { const allauth = window.allauth = window.allauth || {} const webauthnJSON = window.webauthnJSON function dispatchError (exception) { const event = new CustomEvent('allauth.error', { detail: { tags: ['mfa', 'webauthn'], exception }, cancelable: true }) document.dispatchEvent(event) if (!event.defaultPrevented) { console.error(exception) } } async function createCredentials (credentials, passwordless) { credentials = JSON.parse(JSON.stringify(credentials)) const sel = credentials.publicKey.authenticatorSelection if (passwordless != null) { sel.residentKey = passwordless ? 'required' : 'discouraged' sel.requireResidentKey = passwordless sel.userVerification = passwordless ? 'required' : 'discouraged' } return await webauthnJSON.create(credentials) } function signupForm (o) { const signupBtn = document.getElementById(o.ids.signup) return addOrSignupForm(o, signupBtn, null) } function addForm (o) { const addBtn = document.getElementById(o.ids.add) const passwordlessCb = o.ids.passwordless ? document.getElementById(o.ids.passwordless) : null const passwordlessFn = () => passwordlessCb ? passwordlessCb.checked : false return addOrSignupForm(o, addBtn, passwordlessFn) } function addOrSignupForm (o, actionBtn, passwordlessFn) { const credentialInput = document.getElementById(o.ids.credential) const form = credentialInput.closest('form') actionBtn.addEventListener('click', async function () { const passwordless = passwordlessFn ? passwordlessFn() : undefined try { const credential = await createCredentials(o.data.creation_options, passwordless) credentialInput.value = JSON.stringify(credential) form.submit() } catch (e) { dispatchError(e) } }) } function loginForm (o) { const loginBtn = document.getElementById(o.ids.login) const form = loginBtn.form const credentialInput = document.getElementById(o.ids.credential) loginBtn.addEventListener('click', async function (e) { e.preventDefault() try { const response = await fetch(form.action, { method: 'GET', headers: { Accept: 'application/json' } }) if (!response.ok) { throw new Error('Unable to fetch passkey data from server.') } const data = await response.json() const credential = await webauthnJSON.get(data.request_options) credentialInput.value = JSON.stringify(credential) form.submit() } catch (e) { dispatchError(e) } }) } function authenticateForm (o) { const authenticateBtn = document.getElementById(o.ids.authenticate) const credentialInput = document.getElementById(o.ids.credential) const form = credentialInput.closest('form') authenticateBtn.addEventListener('click', async function (e) { e.preventDefault() try { const credential = await webauthnJSON.get(o.data.request_options) credentialInput.value = JSON.stringify(credential) form.submit() } catch (e) { dispatchError(e) } }) } allauth.webauthn = { forms: { addForm, authenticateForm, loginForm, signupForm } } })() django-allauth-65.0.2/allauth/mfa/totp/000077500000000000000000000000001467545753200177035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/totp/__init__.py000066400000000000000000000000001467545753200220020ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/totp/forms.py000066400000000000000000000025431467545753200214070ustar00rootroot00000000000000from django import forms from django.utils.translation import gettext_lazy as _ from allauth.mfa.adapter import get_adapter from allauth.mfa.internal.flows.add import validate_can_add_authenticator from allauth.mfa.totp.internal import auth class ActivateTOTPForm(forms.Form): code = forms.CharField( label=_("Authenticator code"), widget=forms.TextInput( attrs={"placeholder": _("Code"), "autocomplete": "one-time-code"}, ), ) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) self.secret = auth.get_totp_secret(regenerate=not self.is_bound) def clean_code(self): validate_can_add_authenticator(self.user) code = self.cleaned_data["code"] if not auth.validate_totp_code(self.secret, code): raise get_adapter().validation_error("incorrect_code") return code class DeactivateTOTPForm(forms.Form): def __init__(self, *args, **kwargs): self.authenticator = kwargs.pop("authenticator") super().__init__(*args, **kwargs) def clean(self): cleaned_data = super().clean() adapter = get_adapter() if not adapter.can_delete_authenticator(self.authenticator): raise adapter.validation_error("cannot_delete_authenticator") return cleaned_data django-allauth-65.0.2/allauth/mfa/totp/internal/000077500000000000000000000000001467545753200215175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/totp/internal/__init__.py000066400000000000000000000000001467545753200236160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/totp/internal/auth.py000066400000000000000000000064531467545753200230420ustar00rootroot00000000000000import base64 import hashlib import hmac import secrets import struct import time from django.core.cache import cache from allauth.core import context from allauth.mfa import app_settings from allauth.mfa.models import Authenticator from allauth.mfa.utils import decrypt, encrypt SECRET_SESSION_KEY = "mfa.totp.secret" def generate_totp_secret(length: int = 20) -> str: random_bytes = secrets.token_bytes(length) return base64.b32encode(random_bytes).decode("utf-8") def get_totp_secret(regenerate: bool = False) -> str: secret = None if not regenerate: secret = context.request.session.get(SECRET_SESSION_KEY) if not secret: secret = context.request.session[SECRET_SESSION_KEY] = generate_totp_secret() return secret def hotp_counter_from_time() -> int: current_time = int(time.time()) # Get the current Unix timestamp return current_time // app_settings.TOTP_PERIOD def hotp_value(secret: str, counter: int) -> int: # Convert the counter to a byte array using big-endian encoding counter_bytes = struct.pack(">Q", counter) secret_enc = base64.b32decode(secret.encode("ascii"), casefold=True) # Calculate the HMAC-SHA1 hash using the secret and counter hmac_result = hmac.new(secret_enc, counter_bytes, hashlib.sha1).digest() # Get the last 4 bits of the HMAC result to determine the offset offset = hmac_result[-1] & 0x0F # Extract an 31-bit slice from the HMAC result starting at the offset + 1 bit truncated_hash = bytearray(hmac_result[offset : offset + 4]) truncated_hash[0] = truncated_hash[0] & 0x7F # Convert the truncated hash to an integer value value = struct.unpack(">I", truncated_hash)[0] # Apply modulo to get a value within the specified number of digits value %= 10**app_settings.TOTP_DIGITS return value def format_hotp_value(value: int) -> str: return f"{value:0{app_settings.TOTP_DIGITS}}" def _is_insecure_bypass(code: str) -> bool: return bool(code and app_settings.TOTP_INSECURE_BYPASS_CODE == code) def validate_totp_code(secret: str, code: str) -> bool: if _is_insecure_bypass(code): return True value = hotp_value(secret, hotp_counter_from_time()) return code == format_hotp_value(value) class TOTP: def __init__(self, instance: Authenticator) -> None: self.instance = instance @classmethod def activate(cls, user, secret: str) -> "TOTP": instance = Authenticator( user=user, type=Authenticator.Type.TOTP, data={"secret": encrypt(secret)} ) instance.save() return cls(instance) def validate_code(self, code: str) -> bool: if _is_insecure_bypass(code): return True if self._is_code_used(code): return False secret = decrypt(self.instance.data["secret"]) valid = validate_totp_code(secret, code) if valid: self._mark_code_used(code) return valid def _get_used_cache_key(self, code: str) -> str: return f"allauth.mfa.totp.used?user={self.instance.user_id}&code={code}" def _is_code_used(self, code: str) -> bool: return cache.get(self._get_used_cache_key(code)) == "y" def _mark_code_used(self, code: str) -> None: cache.set(self._get_used_cache_key(code), "y", timeout=app_settings.TOTP_PERIOD) django-allauth-65.0.2/allauth/mfa/totp/internal/flows.py000066400000000000000000000030151467545753200232220ustar00rootroot00000000000000from typing import Optional, Tuple from django.contrib import messages from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal.flows.reauthentication import ( raise_if_reauthentication_required, ) from allauth.mfa import signals from allauth.mfa.base.internal.flows import delete_and_cleanup from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.internal.flows import ( auto_generate_recovery_codes, ) from allauth.mfa.totp.internal.auth import TOTP def activate_totp(request, form) -> Tuple[Authenticator, Optional[Authenticator]]: raise_if_reauthentication_required(request) totp_auth = TOTP.activate(request.user, form.secret).instance signals.authenticator_added.send( sender=Authenticator, request=request, user=request.user, authenticator=totp_auth, ) adapter = get_account_adapter(request) adapter.add_message(request, messages.SUCCESS, "mfa/messages/totp_activated.txt") adapter.send_notification_mail("mfa/email/totp_activated", request.user) rc_auth = auto_generate_recovery_codes(request) return totp_auth, rc_auth def deactivate_totp(request, authenticator: Authenticator) -> None: raise_if_reauthentication_required(request) delete_and_cleanup(request, authenticator) adapter = get_account_adapter(request) adapter.add_message(request, messages.SUCCESS, "mfa/messages/totp_deactivated.txt") adapter.send_notification_mail("mfa/email/totp_deactivated", request.user) django-allauth-65.0.2/allauth/mfa/totp/tests/000077500000000000000000000000001467545753200210455ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/totp/tests/__init__.py000066400000000000000000000000001467545753200231440ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/totp/tests/test_views.py000066400000000000000000000211451467545753200236160ustar00rootroot00000000000000import time from unittest.mock import ANY, patch from django.conf import settings from django.core.cache import cache from django.test import Client from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.account import app_settings from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.mfa.adapter import get_adapter from allauth.mfa.models import Authenticator def test_activate_totp_with_incorrect_code(auth_client, reauthentication_bypass): with reauthentication_bypass(): resp = auth_client.get(reverse("mfa_activate_totp")) resp = auth_client.post( reverse("mfa_activate_totp"), { "code": "123", }, ) assert resp.context["form"].errors == { "code": [get_adapter().error_messages["incorrect_code"]] } @pytest.mark.parametrize("email_verified", [False]) @pytest.mark.parametrize("method", ["get", "post"]) def test_activate_totp_with_unverified_email( auth_client, user, totp_validation_bypass, reauthentication_bypass, method ): with reauthentication_bypass(): if method == "get": resp = auth_client.get(reverse("mfa_activate_totp")) else: resp = auth_client.post(reverse("mfa_activate_totp"), {"code": "123"}) assert resp["location"] == reverse("mfa_index") def test_activate_totp_success( auth_client, totp_validation_bypass, user, reauthentication_bypass, settings, mailoutbox, ): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True with reauthentication_bypass(): resp = auth_client.get(reverse("mfa_activate_totp")) with totp_validation_bypass(): resp = auth_client.post( reverse("mfa_activate_totp"), { "code": "123", }, ) assert resp["location"] == reverse("mfa_view_recovery_codes") assert Authenticator.objects.filter( user=user, type=Authenticator.Type.TOTP ).exists() assert Authenticator.objects.filter( user=user, type=Authenticator.Type.RECOVERY_CODES ).exists() assert len(mailoutbox) == 1 assert "Authenticator App Activated" in mailoutbox[0].subject assert "Authenticator app activated." in mailoutbox[0].body def test_deactivate_totp_success( auth_client, user_with_totp, user_password, settings, mailoutbox ): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True resp = auth_client.get(reverse("mfa_deactivate_totp")) assert resp.status_code == 302 assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.post(resp["location"], {"password": user_password}) assert resp.status_code == 302 resp = auth_client.post(reverse("mfa_deactivate_totp")) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_index") assert len(mailoutbox) == 1 assert "Authenticator App Deactivated" in mailoutbox[0].subject assert "Authenticator app deactivated." in mailoutbox[0].body def test_user_without_totp_deactivate_totp(auth_client): resp = auth_client.get(reverse("mfa_deactivate_totp")) assert resp.status_code == 404 def test_user_with_totp_activate_totp( auth_client, user_with_totp, reauthentication_bypass ): with reauthentication_bypass(): resp = auth_client.get(reverse("mfa_activate_totp")) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_deactivate_totp") def test_totp_login(client, user_with_totp, user_password, totp_validation_bypass): resp = client.post( reverse("account_login"), {"login": user_with_totp.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_authenticate") resp = client.get(reverse("mfa_authenticate")) assert resp.context["request"].user.is_anonymous resp = client.post(reverse("mfa_authenticate"), {"code": "123"}) assert resp.context["form"].errors == { "code": [get_adapter().error_messages["incorrect_code"]] } with totp_validation_bypass(): resp = client.post( reverse("mfa_authenticate"), {"code": "123"}, ) assert resp.status_code == 302 assert resp["location"] == settings.LOGIN_REDIRECT_URL assert client.session[AUTHENTICATION_METHODS_SESSION_KEY] == [ {"method": "password", "at": ANY, "username": user_with_totp.username}, {"method": "mfa", "at": ANY, "id": ANY, "type": Authenticator.Type.TOTP}, ] def test_totp_login_rate_limit( settings, enable_cache, user_with_totp, user_password, client ): settings.ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 3 resp = client.post( reverse("account_login"), {"login": user_with_totp.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_authenticate") for i in range(5): is_locked = i >= 3 resp = client.post( reverse("mfa_authenticate"), { "code": "wrong", }, ) assert resp.context["form"].errors == { "code": [ ( "Too many failed login attempts. Try again later." if is_locked else "Incorrect code." ) ] } def test_cannot_deactivate_totp(auth_client, user_with_totp, user_password): with patch( "allauth.mfa.adapter.DefaultMFAAdapter.can_delete_authenticator" ) as cda_mock: cda_mock.return_value = False resp = auth_client.get(reverse("mfa_deactivate_totp")) assert resp.status_code == 302 assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.post(resp["location"], {"password": user_password}) assert resp.status_code == 302 resp = auth_client.get(reverse("mfa_deactivate_totp")) # When we GET, the form validation error is already on screen assert resp.context["form"].errors == { "__all__": [get_adapter().error_messages["cannot_delete_authenticator"]], } # And, when we POST anyway, it does not work resp = auth_client.post(reverse("mfa_deactivate_totp")) assert resp.status_code == 200 assert resp.context["form"].errors == { "__all__": [get_adapter().error_messages["cannot_delete_authenticator"]], } def test_totp_code_reuse( user_with_totp, user_password, totp_validation_bypass, enable_cache ): for code, time_lapse, expect_success in [ # First use of code, SUCCESS ("123", False, True), # Second use, no time elapsed: FAIL ("123", False, False), # Different code, no time elapsed: SUCCESS ("456", False, True), # Again, previous code, no time elapsed: FAIL ("123", False, False), # Previous code, but time elapsed: SUCCESS ("123", True, True), ]: if time_lapse: cache.clear() client = Client() resp = client.post( reverse("account_login"), {"login": user_with_totp.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_authenticate") # Note that this bypass only bypasses the actual code check, not the # re-use check we're testing here. with totp_validation_bypass(): resp = client.post( reverse("mfa_authenticate"), {"code": code}, ) if expect_success: assert resp.status_code == 302 assert resp["location"] == settings.LOGIN_REDIRECT_URL else: assert resp.status_code == 200 assert resp.context["form"].errors == { "code": [get_adapter().error_messages["incorrect_code"]] } def test_totp_stage_expires(client, user_with_totp, user_password): resp = client.post( reverse("account_login"), {"login": user_with_totp.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_authenticate") resp = client.get(reverse("mfa_authenticate")) assert resp.status_code == 200 assertTemplateUsed(resp, "mfa/authenticate.html") with patch( "allauth.account.internal.stagekit.time.time", return_value=time.time() + 1.1 * app_settings.LOGIN_TIMEOUT, ): resp = client.get(reverse("mfa_authenticate")) assert resp.status_code == 302 assert resp["location"] == reverse("account_login") django-allauth-65.0.2/allauth/mfa/totp/urls.py000066400000000000000000000005061467545753200212430ustar00rootroot00000000000000from typing import List, Union from django.urls import URLPattern, URLResolver, path from allauth.mfa.totp import views urlpatterns: List[Union[URLPattern, URLResolver]] = [ path("activate/", views.activate_totp, name="mfa_activate_totp"), path("deactivate/", views.deactivate_totp, name="mfa_deactivate_totp"), ] django-allauth-65.0.2/allauth/mfa/totp/views.py000066400000000000000000000106431467545753200214160ustar00rootroot00000000000000import base64 from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator from django.views.generic.edit import FormView from allauth.account import app_settings as account_settings from allauth.account.decorators import reauthentication_required from allauth.mfa import app_settings from allauth.mfa.adapter import get_adapter from allauth.mfa.internal.flows.add import redirect_if_add_not_allowed from allauth.mfa.models import Authenticator from allauth.mfa.totp.forms import ActivateTOTPForm, DeactivateTOTPForm from allauth.mfa.totp.internal import flows from allauth.mfa.utils import is_mfa_enabled from allauth.utils import get_form_class @method_decorator(redirect_if_add_not_allowed, name="dispatch") @method_decorator(reauthentication_required, name="dispatch") class ActivateTOTPView(FormView): form_class = ActivateTOTPForm template_name = "mfa/totp/activate_form." + account_settings.TEMPLATE_EXTENSION def dispatch(self, request, *args, **kwargs): if is_mfa_enabled(request.user, [Authenticator.Type.TOTP]): return HttpResponseRedirect(reverse("mfa_deactivate_totp")) return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) adapter = get_adapter() totp_url = adapter.build_totp_url( self.request.user, ret["form"].secret, ) totp_svg = adapter.build_totp_svg(totp_url) base64_data = base64.b64encode(totp_svg.encode("utf8")).decode("utf-8") totp_data_uri = f"data:image/svg+xml;base64,{base64_data}" ret.update( { "totp_svg": totp_svg, "totp_svg_data_uri": totp_data_uri, "totp_url": totp_url, } ) return ret def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request.user return ret def get_form_class(self): return get_form_class(app_settings.FORMS, "activate_totp", self.form_class) def get_success_url(self): if self.did_generate_recovery_codes: return reverse("mfa_view_recovery_codes") return reverse("mfa_index") def form_valid(self, form): totp_auth, rc_auth = flows.activate_totp(self.request, form) self.did_generate_recovery_codes = bool(rc_auth) return super().form_valid(form) activate_totp = ActivateTOTPView.as_view() @method_decorator(login_required, name="dispatch") class DeactivateTOTPView(FormView): form_class = DeactivateTOTPForm template_name = "mfa/totp/deactivate_form." + account_settings.TEMPLATE_EXTENSION success_url = reverse_lazy("mfa_index") def dispatch(self, request, *args, **kwargs): self.authenticator = get_object_or_404( Authenticator, user=self.request.user, type=Authenticator.Type.TOTP, ) if not is_mfa_enabled(request.user, [Authenticator.Type.TOTP]): return HttpResponseRedirect(reverse("mfa_activate_totp")) return self._dispatch(request, *args, **kwargs) @method_decorator(reauthentication_required) def _dispatch(self, request, *args, **kwargs): """There's no point to reauthenticate when MFA is not enabled, so the `is_mfa_enabled` check needs to go first, which is why we cannot slap a `reauthentication_required` decorator on the `dispatch` directly. """ return super().dispatch(request, *args, **kwargs) def get_form_kwargs(self): ret = super().get_form_kwargs() ret["authenticator"] = self.authenticator # The deactivation form does not require input, yet, can generate # validation errors in case deactivation is not allowed. We want to # immediately present such errors even before the user actually posts # the form, which is why we put an empty data payload in here. ret.setdefault("data", {}) return ret def get_form_class(self): return get_form_class(app_settings.FORMS, "deactivate_totp", self.form_class) def form_valid(self, form): flows.deactivate_totp(self.request, self.authenticator) return super().form_valid(form) deactivate_totp = DeactivateTOTPView.as_view() django-allauth-65.0.2/allauth/mfa/urls.py000066400000000000000000000012021467545753200202470ustar00rootroot00000000000000from typing import List, Union from django.urls import URLPattern, URLResolver, include, path from allauth.mfa import app_settings urlpatterns: List[Union[URLPattern, URLResolver]] = [ path("", include("allauth.mfa.base.urls")) ] if "totp" in app_settings.SUPPORTED_TYPES: urlpatterns.append(path("totp/", include("allauth.mfa.totp.urls"))) if "recovery_codes" in app_settings.SUPPORTED_TYPES: urlpatterns.append( path("recovery-codes/", include("allauth.mfa.recovery_codes.urls")) ) if "webauthn" in app_settings.SUPPORTED_TYPES: urlpatterns.append(path("webauthn/", include("allauth.mfa.webauthn.urls"))) django-allauth-65.0.2/allauth/mfa/utils.py000066400000000000000000000004331467545753200204270ustar00rootroot00000000000000from allauth.mfa.adapter import get_adapter def encrypt(text): return get_adapter().encrypt(text) def decrypt(encrypted_text): return get_adapter().decrypt(encrypted_text) def is_mfa_enabled(user, types=None): return get_adapter().is_mfa_enabled(user, types=types) django-allauth-65.0.2/allauth/mfa/webauthn/000077500000000000000000000000001467545753200205325ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/webauthn/__init__.py000066400000000000000000000000001467545753200226310ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/webauthn/forms.py000066400000000000000000000104511467545753200222330ustar00rootroot00000000000000from django import forms from django.utils.translation import gettext_lazy as _ from allauth.core import context from allauth.mfa import app_settings from allauth.mfa.adapter import get_adapter from allauth.mfa.base.internal.flows import ( check_rate_limit, post_authentication, ) from allauth.mfa.models import Authenticator from allauth.mfa.webauthn.internal import auth, flows class _BaseAddWebAuthnForm(forms.Form): name = forms.CharField(required=False) credential = forms.JSONField(required=True, widget=forms.HiddenInput) def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") initial = kwargs.setdefault("initial", {}) initial.setdefault( "name", get_adapter().generate_authenticator_name( self.user, Authenticator.Type.WEBAUTHN ), ) super().__init__(*args, **kwargs) def clean_name(self): """ We don't want to make `name` a required field, as the WebAuthn ceremony happens before posting the resulting credential, and we don't want to reject a valid credential because of a missing name -- it might be resident already. So, gracefully plug in a name. """ name = self.cleaned_data["name"] if not name: name = get_adapter().generate_authenticator_name( self.user, Authenticator.Type.WEBAUTHN ) return name def clean(self): cleaned_data = super().clean() credential = cleaned_data.get("credential") if credential: # Explicitly parse JSON payload -- otherwise, register_complete() # crashes with some random TypeError and we don't want to do # Pokemon-style exception handling. auth.parse_registration_response(credential) auth.complete_registration(credential) return cleaned_data class AddWebAuthnForm(_BaseAddWebAuthnForm): if app_settings.PASSKEY_LOGIN_ENABLED: passwordless = forms.BooleanField( label=_("Passwordless"), required=False, help_text=_( "Enabling passwordless operation allows you to sign in using just this key, but imposes additional requirements such as biometrics or PIN protection." ), ) class SignupWebAuthnForm(_BaseAddWebAuthnForm): pass class AuthenticateWebAuthnForm(forms.Form): credential = forms.JSONField(required=True, widget=forms.HiddenInput) reauthenticated = False passwordless = False def __init__(self, *args, **kwargs): self.user = kwargs.pop("user") super().__init__(*args, **kwargs) def clean_credential(self): credential = self.cleaned_data["credential"] # Explicitly parse JSON payload -- otherwise, authenticate_complete() # crashes with some random TypeError and we don't want to do # Pokemon-style exception handling. auth.parse_authentication_response(credential) user = self.user if user is None: user = auth.extract_user_from_response(credential) clear_rl = check_rate_limit(user) authenticator = auth.complete_authentication(user, credential) clear_rl() return authenticator def save(self): authenticator = self.cleaned_data["credential"] post_authentication( context.request, authenticator, reauthenticated=self.reauthenticated, passwordless=self.passwordless, ) class LoginWebAuthnForm(AuthenticateWebAuthnForm): reauthenticated = False passwordless = True def __init__(self, *args, **kwargs): super().__init__(*args, user=None, **kwargs) class ReauthenticateWebAuthnForm(AuthenticateWebAuthnForm): reauthenticated = True passwordless = False class EditWebAuthnForm(forms.Form): name = forms.CharField(required=True) def __init__(self, *args, **kwargs): self.instance = kwargs.pop("instance") initial = kwargs.setdefault("initial", {}) initial.setdefault("name", self.instance.wrap().name) super().__init__(*args, **kwargs) def save(self) -> Authenticator: flows.rename_authenticator( context.request, self.instance, self.cleaned_data["name"] ) return self.instance django-allauth-65.0.2/allauth/mfa/webauthn/internal/000077500000000000000000000000001467545753200223465ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/webauthn/internal/__init__.py000066400000000000000000000000001467545753200244450ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/webauthn/internal/auth.py000066400000000000000000000150241467545753200236630ustar00rootroot00000000000000from typing import Any, Dict, List, Optional from django.contrib.auth import get_user_model import fido2.features from fido2.server import Fido2Server from fido2.utils import websafe_decode from fido2.webauthn import ( AttestedCredentialData, AuthenticationResponse, AuthenticatorData, PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity, RegistrationResponse, ResidentKeyRequirement, UserVerificationRequirement, ) from allauth.account.utils import url_str_to_user_pk from allauth.core import context from allauth.mfa import app_settings from allauth.mfa.adapter import get_adapter from allauth.mfa.models import Authenticator fido2.features.webauthn_json_mapping.enabled = True STATE_SESSION_KEY = "mfa.webauthn.state" EXTENSIONS = {"credProps": True} def build_user_payload(user) -> PublicKeyCredentialUserEntity: kwargs = get_adapter().get_public_key_credential_user_entity(user) return PublicKeyCredentialUserEntity(**kwargs) def get_state() -> Optional[Dict]: return context.request.session.get(STATE_SESSION_KEY) def set_state(state: Dict) -> None: context.request.session[STATE_SESSION_KEY] = state def clear_state() -> None: context.request.session.pop(STATE_SESSION_KEY, None) def get_server() -> Fido2Server: rp_kwargs = get_adapter().get_public_key_credential_rp_entity() rp = PublicKeyCredentialRpEntity(**rp_kwargs) verify_origin = None if app_settings.WEBAUTHN_ALLOW_INSECURE_ORIGIN: verify_origin = lambda o: True # noqa server = Fido2Server(rp, verify_origin=verify_origin) return server def parse_registration_response(response: Any) -> RegistrationResponse: try: return RegistrationResponse.from_dict(response) except TypeError: raise get_adapter().validation_error("incorrect_code") def begin_registration(user, passwordless: bool) -> Dict: server = get_server() credentials = get_credentials(user) registration_data, state = server.register_begin( user=build_user_payload(user), credentials=credentials, resident_key_requirement=( ResidentKeyRequirement.REQUIRED if passwordless else ResidentKeyRequirement.DISCOURAGED ), user_verification=( UserVerificationRequirement.REQUIRED if passwordless else UserVerificationRequirement.DISCOURAGED ), extensions=EXTENSIONS, ) set_state(state) return dict(registration_data) def complete_registration(credential: Dict) -> AuthenticatorData: server = get_server() state = get_state() if not state: raise get_adapter().validation_error("incorrect_code") try: binding = server.register_complete(state, credential) except ValueError: # raise ValueError("Wrong challenge in response.") raise get_adapter().validation_error("incorrect_code") clear_state() return binding def get_credentials(user) -> List[AttestedCredentialData]: credentials: List[AttestedCredentialData] = [] authenticators = Authenticator.objects.filter( user=user, type=Authenticator.Type.WEBAUTHN ) for authenticator in authenticators: credential_data = authenticator.wrap().authenticator_data.credential_data if credential_data: credentials.append(authenticator.wrap().authenticator_data.credential_data) return credentials def get_authenticator_by_credential_id( user, credential_id: bytes ) -> Optional[Authenticator]: authenticators = Authenticator.objects.filter( user=user, type=Authenticator.Type.WEBAUTHN ) for authenticator in authenticators: if ( credential_id == authenticator.wrap().authenticator_data.credential_data.credential_id ): return authenticator return None def parse_authentication_response(response: Any) -> AuthenticationResponse: try: return AuthenticationResponse.from_dict(response) except TypeError: raise get_adapter().validation_error("incorrect_code") def begin_authentication(user=None) -> Dict: server = get_server() request_options, state = server.authenticate_begin( credentials=get_credentials(user) if user else [], user_verification=UserVerificationRequirement.PREFERRED, ) set_state(state) return dict(request_options) def extract_user_from_response(response: Dict): try: user_handle = response.get("response", {}).get("userHandle") user_pk = url_str_to_user_pk(websafe_decode(user_handle).decode("utf8")) except (ValueError, TypeError, KeyError): raise get_adapter().validation_error("incorrect_code") user = get_user_model().objects.filter(pk=user_pk).first() if not user: raise get_adapter().validation_error("incorrect_code") return user def complete_authentication(user, response: Dict) -> Authenticator: credentials = get_credentials(user) server = get_server() state = get_state() if not state: raise get_adapter().validation_error("incorrect_code") try: binding = server.authenticate_complete(state, credentials, response) except ValueError as e: # ValueError: Unknown credential ID. raise get_adapter().validation_error("incorrect_code") from e clear_state() authenticator = get_authenticator_by_credential_id(user, binding.credential_id) if not authenticator: raise get_adapter().validation_error("incorrect_code") return authenticator class WebAuthn: def __init__(self, instance): self.instance = instance @classmethod def add(cls, user, name: str, credential: dict) -> "WebAuthn": instance = Authenticator( user=user, type=Authenticator.Type.WEBAUTHN, data={ "name": name, "credential": credential, }, ) instance.save() return cls(instance) @property def name(self) -> str: return self.instance.data["name"] @name.setter def name(self, name: str): self.instance.data["name"] = name @property def authenticator_data(self) -> AuthenticatorData: return parse_registration_response( self.instance.data["credential"] ).response.attestation_object.auth_data @property def is_passwordless(self) -> Optional[bool]: return ( self.instance.data.get("credential", {}) .get("clientExtensionResults", {}) .get("credProps", {}) .get("rk") ) django-allauth-65.0.2/allauth/mfa/webauthn/internal/flows.py000066400000000000000000000074221467545753200240570ustar00rootroot00000000000000from typing import Iterable, Optional, Tuple from django.contrib import messages from django.http import HttpRequest from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.authentication import get_authentication_records from allauth.account.internal import flows from allauth.account.internal.flows.reauthentication import ( raise_if_reauthentication_required, ) from allauth.account.models import Login from allauth.mfa import signals from allauth.mfa.base.internal.flows import ( delete_and_cleanup, post_authentication, ) from allauth.mfa.models import Authenticator from allauth.mfa.recovery_codes.internal.flows import ( auto_generate_recovery_codes, ) from allauth.mfa.webauthn.internal import auth def begin_registration( request: HttpRequest, user, passwordless: bool, signup: bool = False ) -> dict: if not signup: raise_if_reauthentication_required(request) creation_options = auth.begin_registration(user, passwordless) return creation_options def signup_authenticator(request, user, name: str, credential: dict) -> Authenticator: authenticator, rc_authenticator = _signup_or_add_authenticator( request, user, name, credential, signup=True ) return authenticator def add_authenticator( request, name: str, credential: dict ) -> Tuple[Authenticator, Optional[Authenticator]]: raise_if_reauthentication_required(request) return _signup_or_add_authenticator( request, user=request.user, name=name, credential=credential, signup=False, ) def _signup_or_add_authenticator( request, user, name: str, credential: dict, signup: bool = False, ) -> Tuple[Authenticator, Optional[Authenticator]]: authenticator = auth.WebAuthn.add( user, name, credential, ).instance signals.authenticator_added.send( sender=Authenticator, request=request, user=user, authenticator=authenticator, ) adapter = get_account_adapter(request) adapter.add_message(request, messages.SUCCESS, "mfa/messages/webauthn_added.txt") if not signup: adapter.send_notification_mail("mfa/email/webauthn_added", user) rc_authenticator = None if not signup: rc_authenticator = auto_generate_recovery_codes(request) return authenticator, rc_authenticator def remove_authenticators(request, authenticators: Iterable[Authenticator]) -> None: raise_if_reauthentication_required(request) for authenticator in authenticators: remove_authenticator(request, authenticator) def remove_authenticator(request, authenticator: Authenticator): raise_if_reauthentication_required(request) delete_and_cleanup(request, authenticator) adapter = get_account_adapter(request) adapter.add_message(request, messages.SUCCESS, "mfa/messages/webauthn_removed.txt") adapter.send_notification_mail("mfa/email/webauthn_removed", request.user) def perform_passwordless_login(request, authenticator: Authenticator, login: Login): post_authentication(request, authenticator, passwordless=True) return flows.login.perform_login(request, login) def did_use_passwordless_login(request: HttpRequest) -> bool: records = get_authentication_records(request) return any( (record.get("method"), record.get("type"), record.get("passwordless")) == ("mfa", "webauthn", True) for record in records ) def reauthenticate(request: HttpRequest, authenticator: Authenticator): post_authentication(request, authenticator, reauthenticated=True) def rename_authenticator(request, authenticator: Authenticator, name: str): raise_if_reauthentication_required(request) wrapper = authenticator.wrap() wrapper.name = name authenticator.save() django-allauth-65.0.2/allauth/mfa/webauthn/stages.py000066400000000000000000000006601467545753200223740ustar00rootroot00000000000000from allauth.account.stages import LoginStage from allauth.core.internal.httpkit import headed_redirect_response class PasskeySignupStage(LoginStage): key = "mfa_signup_webauthn" urlname = "mfa_signup_webauthn" def handle(self): response, cont = None, True if self.login.state.get("passkey_signup"): response = headed_redirect_response("mfa_signup_webauthn") return response, cont django-allauth-65.0.2/allauth/mfa/webauthn/tests/000077500000000000000000000000001467545753200216745ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/webauthn/tests/__init__.py000066400000000000000000000000001467545753200237730ustar00rootroot00000000000000django-allauth-65.0.2/allauth/mfa/webauthn/tests/test_views.py000066400000000000000000000171031467545753200244440ustar00rootroot00000000000000from unittest.mock import ANY from django.conf import settings from django.contrib.auth import get_user_model from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.mfa.models import Authenticator def test_passkey_login(client, passkey, webauthn_authentication_bypass): with webauthn_authentication_bypass(passkey) as credential: resp = client.get( reverse("mfa_login_webauthn"), HTTP_X_REQUESTED_WITH="XMLHttpRequest" ) assert "request_options" in resp.json() resp = client.post( reverse("mfa_login_webauthn"), data={"credential": credential} ) assert resp["location"] == settings.LOGIN_REDIRECT_URL assert client.session[AUTHENTICATION_METHODS_SESSION_KEY] == [ { "at": ANY, "id": ANY, "method": "mfa", "passwordless": True, "type": "webauthn", } ] def test_reauthenticate( auth_client, passkey, user_with_recovery_codes, webauthn_authentication_bypass ): resp = auth_client.get(reverse("mfa_view_recovery_codes")) assert resp.status_code == 302 assert resp["location"].startswith(reverse("account_reauthenticate")) resp = auth_client.get(reverse("mfa_reauthenticate")) assertTemplateUsed(resp, "mfa/reauthenticate.html") with webauthn_authentication_bypass(passkey) as credential: resp = auth_client.get( reverse("mfa_reauthenticate_webauthn"), ) resp = auth_client.post( reverse("mfa_reauthenticate_webauthn"), data={"credential": credential, "next": "/redir"}, ) assert resp["location"] == "/redir" def test_get_passkey_login_challenge_redirects_if_not_ajax(client): resp = client.get(reverse("mfa_login_webauthn")) assert resp["location"] == reverse("account_login") def test_get_passkey_login_challenge(client, db): resp = client.get( reverse("mfa_login_webauthn"), HTTP_X_REQUESTED_WITH="XMLHttpRequest" ) assert resp.status_code == 200 assert resp["content-type"] == "application/json" data = resp.json() assert data == { "request_options": { "publicKey": { "challenge": ANY, "rpId": "testserver", "allowCredentials": [], "userVerification": "preferred", } } } def test_invalid_passkey_login(client, passkey): resp = client.post(reverse("mfa_login_webauthn"), data={"credential": "{}"}) assert resp["location"] == reverse("account_login") def test_rename_key(auth_client, passkey, reauthentication_bypass): resp = auth_client.get(reverse("mfa_edit_webauthn", kwargs={"pk": passkey.pk})) assert resp["location"].startswith(reverse("account_reauthenticate")) with reauthentication_bypass(): resp = auth_client.get(reverse("mfa_edit_webauthn", kwargs={"pk": passkey.pk})) assertTemplateUsed(resp, "mfa/webauthn/edit_form.html") resp = auth_client.post( reverse("mfa_edit_webauthn", kwargs={"pk": passkey.pk}), data={"name": "Renamed"}, ) assert resp["location"] == reverse("mfa_list_webauthn") passkey.refresh_from_db() assert passkey.data["name"] == "Renamed" assert str(passkey) == "Renamed" def test_remove_key(auth_client, passkey, reauthentication_bypass): resp = auth_client.get(reverse("mfa_remove_webauthn", kwargs={"pk": passkey.pk})) assert resp["location"].startswith(reverse("account_reauthenticate")) with reauthentication_bypass(): resp = auth_client.get( reverse("mfa_remove_webauthn", kwargs={"pk": passkey.pk}) ) assertTemplateUsed(resp, "mfa/webauthn/authenticator_confirm_delete.html") resp = auth_client.post( reverse("mfa_remove_webauthn", kwargs={"pk": passkey.pk}) ) assert resp["location"] == reverse("mfa_list_webauthn") @pytest.mark.parametrize("passwordless", [False, True]) def test_add_key( auth_client, user, webauthn_registration_bypass, reauthentication_bypass, passwordless, ): with webauthn_registration_bypass(user, passwordless) as credential: resp = auth_client.post( reverse("mfa_add_webauthn"), data={"credential": credential} ) assert resp["location"].startswith(reverse("account_reauthenticate")) with reauthentication_bypass(): resp = auth_client.get(reverse("mfa_add_webauthn")) assertTemplateUsed(resp, "mfa/webauthn/add_form.html") with webauthn_registration_bypass(user, passwordless) as credential: resp = auth_client.post( reverse("mfa_add_webauthn"), data={ "credential": credential, "passwordless": "on" if passwordless else "", }, ) assert resp["location"].startswith(reverse("mfa_view_recovery_codes")) authenticator = Authenticator.objects.get( user=user, type=Authenticator.Type.WEBAUTHN ) assert authenticator.wrap().is_passwordless == passwordless Authenticator.objects.filter( user=user, type=Authenticator.Type.RECOVERY_CODES ).exists() def test_list_keys(auth_client): resp = auth_client.get(reverse("mfa_list_webauthn")) assertTemplateUsed(resp, "mfa/webauthn/authenticator_list.html") @pytest.mark.parametrize("email_verified", [False]) @pytest.mark.parametrize("method", ["get", "post"]) def test_add_with_unverified_email( auth_client, user, webauthn_registration_bypass, reauthentication_bypass, method ): with webauthn_registration_bypass(user, False) as credential: if method == "get": resp = auth_client.get(reverse("mfa_add_webauthn")) else: resp = auth_client.post( reverse("mfa_add_webauthn"), data={"credential": credential} ) assert resp["location"] == reverse("mfa_index") def test_passkey_signup(client, db, webauthn_registration_bypass): resp = client.post( reverse("account_signup_by_passkey"), data={"email": "pass@key.org", "username": "passkey"}, ) assert resp["location"] == reverse("mfa_signup_webauthn") resp = client.post(resp["location"]) assert resp.status_code == 200 user = get_user_model().objects.get(email="pass@key.org") with webauthn_registration_bypass(user, True) as credential: resp = client.post( reverse("mfa_signup_webauthn"), data={"credential": credential} ) assert resp["location"] == settings.LOGIN_REDIRECT_URL def test_webauthn_login( client, user_with_passkey, passkey, user_password, webauthn_authentication_bypass ): resp = client.post( reverse("account_login"), {"login": user_with_passkey.username, "password": user_password}, ) assert resp.status_code == 302 assert resp["location"] == reverse("mfa_authenticate") with webauthn_authentication_bypass(passkey) as credential: resp = client.get(reverse("mfa_authenticate")) assert resp.status_code == 200 resp = client.post(reverse("mfa_authenticate"), {"credential": credential}) assert resp.status_code == 302 assert resp["location"] == settings.LOGIN_REDIRECT_URL assert client.session[AUTHENTICATION_METHODS_SESSION_KEY] == [ {"method": "password", "at": ANY, "username": user_with_passkey.username}, {"method": "mfa", "at": ANY, "id": ANY, "type": Authenticator.Type.WEBAUTHN}, ] django-allauth-65.0.2/allauth/mfa/webauthn/urls.py000066400000000000000000000022251467545753200220720ustar00rootroot00000000000000from typing import List, Union from django.urls import URLPattern, URLResolver, include, path from allauth.mfa import app_settings from allauth.mfa.webauthn import views urlpatterns: List[Union[URLPattern, URLResolver]] = [ path("", views.list_webauthn, name="mfa_list_webauthn"), path("add/", views.add_webauthn, name="mfa_add_webauthn"), path( "reauthenticate/", views.reauthenticate_webauthn, name="mfa_reauthenticate_webauthn", ), path( "keys//", include( [ path( "remove/", views.remove_webauthn, name="mfa_remove_webauthn", ), path( "edit/", views.edit_webauthn, name="mfa_edit_webauthn", ), ] ), ), ] if app_settings.PASSKEY_LOGIN_ENABLED: urlpatterns.append(path("login/", views.login_webauthn, name="mfa_login_webauthn")) if app_settings.PASSKEY_SIGNUP_ENABLED: urlpatterns.append( path("signup/", views.signup_webauthn, name="mfa_signup_webauthn") ) django-allauth-65.0.2/allauth/mfa/webauthn/views.py000066400000000000000000000163211467545753200222440ustar00rootroot00000000000000from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect, JsonResponse from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator from django.views.generic.edit import DeleteView, FormView, UpdateView from django.views.generic.list import ListView from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.decorators import reauthentication_required from allauth.account.internal.decorators import login_stage_required from allauth.account.mixins import ( NextRedirectMixin, RedirectAuthenticatedUserMixin, ) from allauth.account.models import Login from allauth.account.views import BaseReauthenticateView from allauth.mfa.internal.flows.add import redirect_if_add_not_allowed from allauth.mfa.models import Authenticator from allauth.mfa.webauthn.forms import ( AddWebAuthnForm, EditWebAuthnForm, LoginWebAuthnForm, ReauthenticateWebAuthnForm, SignupWebAuthnForm, ) from allauth.mfa.webauthn.internal import auth, flows from allauth.mfa.webauthn.stages import PasskeySignupStage @method_decorator(redirect_if_add_not_allowed, name="dispatch") @method_decorator(reauthentication_required, name="dispatch") class AddWebAuthnView(FormView): form_class = AddWebAuthnForm template_name = "mfa/webauthn/add_form." + account_settings.TEMPLATE_EXTENSION def get_context_data(self, **kwargs): ret = super().get_context_data() creation_options = auth.begin_registration(self.request.user, False) ret["js_data"] = {"creation_options": creation_options} return ret def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request.user return ret def get_success_url(self): if self.did_generate_recovery_codes: return reverse("mfa_view_recovery_codes") return reverse("mfa_index") def form_valid(self, form): auth, rc_auth = flows.add_authenticator( self.request, name=form.cleaned_data["name"], credential=form.cleaned_data["credential"], ) self.did_generate_recovery_codes = bool(rc_auth) return super().form_valid(form) add_webauthn = AddWebAuthnView.as_view() @method_decorator(login_required, name="dispatch") class ListWebAuthnView(ListView): template_name = ( "mfa/webauthn/authenticator_list." + account_settings.TEMPLATE_EXTENSION ) context_object_name = "authenticators" def get_queryset(self): return Authenticator.objects.filter( user=self.request.user, type=Authenticator.Type.WEBAUTHN ) list_webauthn = ListWebAuthnView.as_view() @method_decorator(reauthentication_required, name="dispatch") class RemoveWebAuthnView(NextRedirectMixin, DeleteView): object: Authenticator # https://github.com/typeddjango/django-stubs/issues/1227 template_name = ( "mfa/webauthn/authenticator_confirm_delete." + account_settings.TEMPLATE_EXTENSION ) success_url = reverse_lazy("mfa_list_webauthn") def get_queryset(self): return Authenticator.objects.filter( user=self.request.user, type=Authenticator.Type.WEBAUTHN ) def form_valid(self, form): authenticator = self.get_object() flows.remove_authenticator(self.request, authenticator) return HttpResponseRedirect(self.get_success_url()) remove_webauthn = RemoveWebAuthnView.as_view() class LoginWebAuthnView(RedirectAuthenticatedUserMixin, FormView): form_class = LoginWebAuthnForm def get(self, request, *args, **kwargs): if get_account_adapter().is_ajax(request): request_options = auth.begin_authentication(user=None) data = {"request_options": request_options} return JsonResponse(data) return HttpResponseRedirect(reverse("account_login")) def form_invalid(self, form): for message in form.errors.get("credential", []): get_account_adapter().add_message( self.request, messages.ERROR, message=message ) return HttpResponseRedirect(reverse("account_login")) def form_valid(self, form): authenticator = form.cleaned_data["credential"] redirect_url = None login = Login(user=authenticator.user, redirect_url=redirect_url) return flows.perform_passwordless_login(self.request, authenticator, login) login_webauthn = LoginWebAuthnView.as_view() @method_decorator(login_required, name="dispatch") class ReauthenticateWebAuthnView(BaseReauthenticateView): form_class = ReauthenticateWebAuthnForm template_name = "mfa/webauthn/reauthenticate." + account_settings.TEMPLATE_EXTENSION def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request.user return ret def form_invalid(self, form): for message in form.errors.get("credential", []): get_account_adapter().add_message( self.request, messages.ERROR, message=message ) return HttpResponseRedirect(reverse("account_login")) def form_valid(self, form): authenticator = form.cleaned_data["credential"] flows.reauthenticate(self.request, authenticator) return super().form_valid(form) def get_context_data(self, **kwargs): ret = super().get_context_data() request_options = auth.begin_authentication(self.request.user) ret["js_data"] = {"request_options": request_options} return ret reauthenticate_webauthn = ReauthenticateWebAuthnView.as_view() @method_decorator(reauthentication_required, name="dispatch") class EditWebAuthnView(NextRedirectMixin, UpdateView): form_class = EditWebAuthnForm template_name = "mfa/webauthn/edit_form." + account_settings.TEMPLATE_EXTENSION success_url = reverse_lazy("mfa_list_webauthn") def get_queryset(self): return Authenticator.objects.filter( user=self.request.user, type=Authenticator.Type.WEBAUTHN ) edit_webauthn = EditWebAuthnView.as_view() @method_decorator( login_stage_required( stage=PasskeySignupStage.key, redirect_urlname="account_signup" ), name="dispatch", ) class SignupWebAuthnView(FormView): form_class = SignupWebAuthnForm template_name = "mfa/webauthn/signup_form." + account_settings.TEMPLATE_EXTENSION def get_context_data(self, **kwargs): ret = super().get_context_data() creation_options = auth.begin_registration( self.request._login_stage.login.user, True ) ret["js_data"] = {"creation_options": creation_options} return ret def get_form_kwargs(self): ret = super().get_form_kwargs() ret["user"] = self.request._login_stage.login.user return ret def form_valid(self, form): flows.signup_authenticator( self.request, user=self.request._login_stage.login.user, name=form.cleaned_data["name"], credential=form.cleaned_data["credential"], ) return self.request._login_stage.exit() signup_webauthn = SignupWebAuthnView.as_view() django-allauth-65.0.2/allauth/models.py000066400000000000000000000000001467545753200177750ustar00rootroot00000000000000django-allauth-65.0.2/allauth/ratelimit.py000066400000000000000000000003231467545753200205140ustar00rootroot00000000000000import warnings from allauth.core.ratelimit import clear, consume, consume_or_429 __all__ = ["consume", "consume_or_429", "clear"] warnings.warn("allauth.ratelimit is deprecated, use allauth.core.ratelimit") django-allauth-65.0.2/allauth/socialaccount/000077500000000000000000000000001467545753200210015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/__init__.py000066400000000000000000000000001467545753200231000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/adapter.py000066400000000000000000000340421467545753200227760ustar00rootroot00000000000000import functools import warnings from django.core.exceptions import ( ImproperlyConfigured, MultipleObjectsReturned, ) from django.db.models import Q from django.urls import reverse from django.utils.crypto import get_random_string from django.utils.translation import gettext_lazy as _ from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.utils import user_email, user_field, user_username from allauth.core.internal.adapter import BaseAdapter from allauth.utils import ( deserialize_instance, import_attribute, serialize_instance, valid_email_or_none, ) from . import app_settings class DefaultSocialAccountAdapter(BaseAdapter): """The adapter class allows you to override various functionality of the ``allauth.socialaccount`` app. To do so, point ``settings.SOCIALACCOUNT_ADAPTER`` to your own class that derives from ``DefaultSocialAccountAdapter`` and override the behavior by altering the implementation of the methods according to your own needs. """ error_messages = { "email_taken": _( "An account already exists with this email address." " Please sign in to that account first, then connect" " your %s account." ), "invalid_token": _("Invalid token."), "no_password": _("Your account has no password set up."), "no_verified_email": _("Your account has no verified email address."), "disconnect_last": _( "You cannot disconnect your last remaining third-party account." ), "connected_other": _( "The third-party account is already connected to a different account." ), } def pre_social_login(self, request, sociallogin): """ Invoked just after a user successfully authenticates via a social provider, but before the login is actually processed (and before the pre_social_login signal is emitted). You can use this hook to intervene, e.g. abort the login by raising an ImmediateHttpResponse Why both an adapter hook and the signal? Intervening in e.g. the flow from within a signal handler is bad -- multiple handlers may be active and are executed in undetermined order. """ pass def on_authentication_error( self, request, provider, error=None, exception=None, extra_context=None, ): """ Invoked when there is an error in the authentication cycle. In this case, pre_social_login will not be reached. You can use this hook to intervene, e.g. redirect to an educational flow by raising an ImmediateHttpResponse. """ if hasattr(self, "authentication_error"): warnings.warn( "adapter.authentication_error() is deprecated, use adapter.on_authentication_error()" ) self.authentication_error( request, provider.id, error=error, exception=exception, extra_context=extra_context, ) def new_user(self, request, sociallogin): """ Instantiates a new User instance. """ return get_account_adapter().new_user(request) def save_user(self, request, sociallogin, form=None): """ Saves a newly signed up social login. In case of auto-signup, the signup form is not available. """ u = sociallogin.user u.set_unusable_password() if form: get_account_adapter().save_user(request, u, form) else: get_account_adapter().populate_username(request, u) sociallogin.save(request) return u def populate_user(self, request, sociallogin, data): """ Hook that can be used to further populate the user instance. For convenience, we populate several common fields. Note that the user instance being populated represents a suggested User instance that represents the social user that is in the process of being logged in. The User instance need not be completely valid and conflict free. For example, verifying whether or not the username already exists, is not a responsibility. """ username = data.get("username") first_name = data.get("first_name") last_name = data.get("last_name") email = data.get("email") name = data.get("name") user = sociallogin.user user_username(user, username or "") user_email(user, valid_email_or_none(email) or "") name_parts = (name or "").partition(" ") user_field(user, "first_name", first_name or name_parts[0]) user_field(user, "last_name", last_name or name_parts[2]) return user def get_connect_redirect_url(self, request, socialaccount): """ Returns the default URL to redirect to after successfully connecting a social account. """ url = reverse("socialaccount_connections") return url def validate_disconnect(self, account, accounts) -> None: """ Validate whether or not the socialaccount account can be safely disconnected. """ pass def is_auto_signup_allowed(self, request, sociallogin): # If email is specified, check for duplicate and if so, no auto signup. auto_signup = app_settings.AUTO_SIGNUP return auto_signup def is_open_for_signup(self, request, sociallogin): """ Checks whether or not the site is open for signups. Next to simply returning True/False you can also intervene the regular flow by raising an ImmediateHttpResponse """ return get_account_adapter(request).is_open_for_signup(request) def get_signup_form_initial_data(self, sociallogin): user = sociallogin.user initial = { "email": user_email(user) or "", "username": user_username(user) or "", "first_name": user_field(user, "first_name") or "", "last_name": user_field(user, "last_name") or "", } return initial def deserialize_instance(self, model, data): return deserialize_instance(model, data) def serialize_instance(self, instance): return serialize_instance(instance) def list_providers(self, request): from allauth.socialaccount.providers import registry ret = [] provider_classes = registry.get_class_list() apps = self.list_apps(request) apps_map = {} for app in apps: apps_map.setdefault(app.provider, []).append(app) for provider_class in provider_classes: provider_apps = apps_map.get(provider_class.id, []) if not provider_apps: if provider_class.uses_apps: continue provider_apps = [None] for app in provider_apps: provider = provider_class(request=request, app=app) ret.append(provider) return ret def get_provider(self, request, provider, client_id=None): """Looks up a `provider`, supporting subproviders by looking up by `provider_id`. """ from allauth.socialaccount.providers import registry provider_class = registry.get_class(provider) if provider_class is None or provider_class.uses_apps: app = self.get_app(request, provider=provider, client_id=client_id) if not provider_class: # In this case, the `provider` argument passed was a # `provider_id`. provider_class = registry.get_class(app.provider) if not provider_class: raise ImproperlyConfigured(f"unknown provider: {app.provider}") return provider_class(request, app=app) elif provider_class: assert not provider_class.uses_apps return provider_class(request, app=None) else: raise ImproperlyConfigured(f"unknown provider: {app.provider}") def list_apps(self, request, provider=None, client_id=None): """SocialApp's can be setup in the database, or, via `settings.SOCIALACCOUNT_PROVIDERS`. This methods returns a uniform list of all known apps matching the specified criteria, and blends both (db/settings) sources of data. """ # NOTE: Avoid loading models at top due to registry boot... from allauth.socialaccount.models import SocialApp # Map provider to the list of apps. provider_to_apps = {} # First, populate it with the DB backed apps. if request: db_apps = SocialApp.objects.on_site(request) else: db_apps = SocialApp.objects.all() if provider: db_apps = db_apps.filter(Q(provider=provider) | Q(provider_id=provider)) if client_id: db_apps = db_apps.filter(client_id=client_id) for app in db_apps: apps = provider_to_apps.setdefault(app.provider, []) apps.append(app) # Then, extend it with the settings backed apps. for p, pcfg in app_settings.PROVIDERS.items(): app_configs = pcfg.get("APPS") if app_configs is None: app_config = pcfg.get("APP") if app_config is None: continue app_configs = [app_config] apps = provider_to_apps.setdefault(p, []) for config in app_configs: app = SocialApp(provider=p) for field in [ "name", "provider_id", "client_id", "secret", "key", "settings", ]: if field in config: setattr(app, field, config[field]) if "certificate_key" in config: warnings.warn("'certificate_key' should be moved into app.settings") app.settings["certificate_key"] = config["certificate_key"] if client_id and app.client_id != client_id: continue if ( provider and app.provider_id != provider and app.provider != provider ): continue apps.append(app) # Flatten the list of apps. apps = [] for provider_apps in provider_to_apps.values(): apps.extend(provider_apps) return apps def get_app(self, request, provider, client_id=None): from allauth.socialaccount.models import SocialApp apps = self.list_apps(request, provider=provider, client_id=client_id) if len(apps) > 1: visible_apps = [app for app in apps if not app.settings.get("hidden")] if len(visible_apps) != 1: raise MultipleObjectsReturned apps = visible_apps elif len(apps) == 0: raise SocialApp.DoesNotExist() return apps[0] def send_notification_mail(self, *args, **kwargs): return get_account_adapter().send_notification_mail(*args, **kwargs) def get_requests_session(self): import requests session = requests.Session() session.request = functools.partial( session.request, timeout=app_settings.REQUESTS_TIMEOUT ) return session def is_email_verified(self, provider, email): """ Returns ``True`` iff the given email encountered during a social login for the given provider is to be assumed verified. This can be configured with a ``"verified_email"`` key in the provider app settings, or a ``"VERIFIED_EMAIL"`` in the global provider settings (``SOCIALACCOUNT_PROVIDERS``). Both can be set to ``False`` or ``True``, or, a list of domains to match email addresses against. """ verified_email = None if provider.app: verified_email = provider.app.settings.get("verified_email") if verified_email is None: settings = provider.get_settings() verified_email = settings.get("VERIFIED_EMAIL", False) if isinstance(verified_email, bool): pass elif isinstance(verified_email, list): email_domain = email.partition("@")[2].lower() verified_domains = [d.lower() for d in verified_email] verified_email = email_domain in verified_domains else: raise ImproperlyConfigured("verified_email wrongly configured") return verified_email def can_authenticate_by_email(self, login, email): """ Returns ``True`` iff authentication by email is active for this login/email. This can be configured with a ``"email_authentication"`` key in the provider app settings, or a ``"VERIFIED_EMAIL"`` in the global provider settings (``SOCIALACCOUNT_PROVIDERS``). """ ret = None provider = login.account.get_provider() if provider.app: ret = provider.app.settings.get("email_authentication") if ret is None: ret = app_settings.EMAIL_AUTHENTICATION or provider.get_settings().get( "EMAIL_AUTHENTICATION", False ) return ret def generate_state_param(self, state: dict) -> str: """ To preserve certain state before the handshake with the provider takes place, and be able to verify/use that state later on, a `state` parameter is typically passed to the provider. By default, a random string sufficies as the state parameter value is actually just a reference/pointer to the actual state. You can use this adapter method to alter the generation of the `state` parameter. """ from allauth.socialaccount.internal.statekit import STATE_ID_LENGTH return get_random_string(STATE_ID_LENGTH) def get_adapter(request=None): return import_attribute(app_settings.ADAPTER)(request) django-allauth-65.0.2/allauth/socialaccount/admin.py000066400000000000000000000037521467545753200224520ustar00rootroot00000000000000from typing import List from django import forms from django.contrib import admin from allauth import app_settings from allauth.account.adapter import get_adapter from allauth.socialaccount import providers from allauth.socialaccount.models import SocialAccount, SocialApp, SocialToken class SocialAppForm(forms.ModelForm): class Meta: model = SocialApp exclude: List[str] = [] widgets = { "client_id": forms.TextInput(attrs={"size": "100"}), "key": forms.TextInput(attrs={"size": "100"}), "secret": forms.TextInput(attrs={"size": "100"}), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["provider"] = forms.ChoiceField( choices=providers.registry.as_choices() ) class SocialAppAdmin(admin.ModelAdmin): form = SocialAppForm list_display = ( "name", "provider", ) filter_horizontal = ("sites",) if app_settings.SITES_ENABLED else () class SocialAccountAdmin(admin.ModelAdmin): search_fields = [] raw_id_fields = ("user",) list_display = ("user", "uid", "provider") list_filter = ("provider",) def get_search_fields(self, request): base_fields = get_adapter().get_user_search_fields() return list(map(lambda a: "user__" + a, base_fields)) class SocialTokenAdmin(admin.ModelAdmin): raw_id_fields = ( "app", "account", ) list_display = ("app", "account", "truncated_token", "expires_at") list_filter = ("app", "app__provider", "expires_at") def truncated_token(self, token): max_chars = 40 ret = token.token if len(ret) > max_chars: ret = ret[0:max_chars] + "...(truncated)" return ret truncated_token.short_description = "Token" # type: ignore[attr-defined] admin.site.register(SocialApp, SocialAppAdmin) admin.site.register(SocialToken, SocialTokenAdmin) admin.site.register(SocialAccount, SocialAccountAdmin) django-allauth-65.0.2/allauth/socialaccount/app_settings.py000066400000000000000000000124031467545753200240530ustar00rootroot00000000000000class AppSettings: def __init__(self, prefix): self.prefix = prefix def _setting(self, name, dflt): from allauth.utils import get_setting return get_setting(self.prefix + name, dflt) @property def QUERY_EMAIL(self): """ Request email address from 3rd party account provider? E.g. using OpenID AX """ from allauth.account import app_settings as account_settings return self._setting("QUERY_EMAIL", account_settings.EMAIL_REQUIRED) @property def AUTO_SIGNUP(self): """ Attempt to bypass the signup form by using fields (e.g. username, email) retrieved from the social account provider. If a conflict arises due to a duplicate email signup form will still kick in. """ return self._setting("AUTO_SIGNUP", True) @property def PROVIDERS(self): """ Provider specific settings """ ret = self._setting("PROVIDERS", {}) oidc = ret.get("openid_connect") if oidc: ret["openid_connect"] = self._migrate_oidc(oidc) return ret def _migrate_oidc(self, oidc): servers = oidc.get("SERVERS") if servers is None: return oidc ret = {} apps = [] for server in servers: app = dict(**server["APP"]) app_settings = {} if "token_auth_method" in server: app_settings["token_auth_method"] = server["token_auth_method"] app_settings["server_url"] = server["server_url"] app.update( { "name": server.get("name", ""), "provider_id": server["id"], "settings": app_settings, } ) assert app["provider_id"] apps.append(app) ret["APPS"] = apps return ret @property def EMAIL_REQUIRED(self): """ The user is required to hand over an email address when signing up """ from allauth.account import app_settings as account_settings return self._setting("EMAIL_REQUIRED", account_settings.EMAIL_REQUIRED) @property def EMAIL_VERIFICATION(self): """ See email verification method. When `None`, the default `allauth.account` logic kicks in. """ return self._setting("EMAIL_VERIFICATION", None) @property def EMAIL_AUTHENTICATION(self): """Consider a scenario where a social login occurs, and the social account comes with a verified email address (verified by the account provider), but that email address is already taken by a local user account. Additionally, assume that the local user account does not have any social account connected. Now, if the provider can be fully trusted, you can argue that we should treat this scenario as a login to the existing local user account even if the local account does not already have the social account connected, because -- according to the provider -- the user logging in has ownership of the email address. This is how this scenario is handled when `EMAIL_AUTHENTICATION` is set to `True`. As this implies that an untrustworthy provider can login to any local account by fabricating social account data, this setting defaults to `False`. Only set it to `True` if you are using providers that can be fully trusted. """ return self._setting("EMAIL_AUTHENTICATION", False) @property def EMAIL_AUTHENTICATION_AUTO_CONNECT(self): """In case email authentication is applied, this setting controls whether or not the social account is automatically connected to the local account. In case of ``False`` (the default) the local account remains unchanged during the login. In case of ``True``, the social account for which the email matched, is automatically added to the list of social accounts connected to the local account. As a result, even if the user were to change the email address afterwards, social login would still be possible when using ``True``, but not in case of ``False``. """ return self._setting("EMAIL_AUTHENTICATION_AUTO_CONNECT", False) @property def ADAPTER(self): return self._setting( "ADAPTER", "allauth.socialaccount.adapter.DefaultSocialAccountAdapter", ) @property def FORMS(self): return self._setting("FORMS", {}) @property def LOGIN_ON_GET(self): return self._setting("LOGIN_ON_GET", False) @property def STORE_TOKENS(self): return self._setting("STORE_TOKENS", False) @property def UID_MAX_LENGTH(self): return 191 @property def SOCIALACCOUNT_STR(self): return self._setting("SOCIALACCOUNT_STR", None) @property def REQUESTS_TIMEOUT(self): return self._setting("REQUESTS_TIMEOUT", 5) @property def OPENID_CONNECT_URL_PREFIX(self): return self._setting("OPENID_CONNECT_URL_PREFIX", "oidc") _app_settings = AppSettings("SOCIALACCOUNT_") def __getattr__(name): # See https://peps.python.org/pep-0562/ return getattr(_app_settings, name) django-allauth-65.0.2/allauth/socialaccount/apps.py000066400000000000000000000006631467545753200223230ustar00rootroot00000000000000from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ from allauth import app_settings class SocialAccountConfig(AppConfig): name = "allauth.socialaccount" verbose_name = _("Social Accounts") default_auto_field = app_settings.DEFAULT_AUTO_FIELD or "django.db.models.AutoField" def ready(self): from allauth.socialaccount.providers import registry registry.load() django-allauth-65.0.2/allauth/socialaccount/conftest.py000066400000000000000000000017171467545753200232060ustar00rootroot00000000000000import pytest from allauth.account.models import EmailAddress from allauth.socialaccount.models import ( SocialAccount, SocialLogin, SocialToken, ) @pytest.fixture def sociallogin_factory(user_factory): def factory( email=None, username=None, with_email=True, provider="unittest-server", uid="123", email_verified=True, with_token=False, ): user = user_factory( username=username, email=email, commit=False, with_email=with_email ) account = SocialAccount(provider=provider, uid=uid) sociallogin = SocialLogin(user=user, account=account) if with_email: sociallogin.email_addresses = [ EmailAddress(email=user.email, verified=email_verified, primary=True) ] if with_token: sociallogin.token = SocialToken(token="123", token_secret="456") return sociallogin return factory django-allauth-65.0.2/allauth/socialaccount/forms.py000066400000000000000000000040031467545753200224760ustar00rootroot00000000000000from django import forms from allauth.account.forms import BaseSignupForm from allauth.socialaccount.internal import flows from . import app_settings from .adapter import get_adapter from .models import SocialAccount class SignupForm(BaseSignupForm): def __init__(self, *args, **kwargs): self.sociallogin = kwargs.pop("sociallogin") initial = get_adapter().get_signup_form_initial_data(self.sociallogin) kwargs.update( { "initial": initial, "email_required": kwargs.get( "email_required", app_settings.EMAIL_REQUIRED ), } ) super(SignupForm, self).__init__(*args, **kwargs) def save(self, request): adapter = get_adapter() user = adapter.save_user(request, self.sociallogin, form=self) self.custom_signup(request, user) return user def validate_unique_email(self, value): try: return super(SignupForm, self).validate_unique_email(value) except forms.ValidationError: raise get_adapter().validation_error( "email_taken", self.sociallogin.account.get_provider().name ) class DisconnectForm(forms.Form): account = forms.ModelChoiceField( queryset=SocialAccount.objects.none(), widget=forms.RadioSelect, required=True, ) def __init__(self, *args, **kwargs): self.request = kwargs.pop("request") self.accounts = SocialAccount.objects.filter(user=self.request.user) super(DisconnectForm, self).__init__(*args, **kwargs) self.fields["account"].queryset = self.accounts def clean(self): cleaned_data = super(DisconnectForm, self).clean() account = cleaned_data.get("account") if account: flows.connect.validate_disconnect(self.request, account) return cleaned_data def save(self): account = self.cleaned_data["account"] flows.connect.disconnect(self.request, account) django-allauth-65.0.2/allauth/socialaccount/helpers.py000066400000000000000000000043231467545753200230170ustar00rootroot00000000000000from django.http import HttpResponseRedirect from django.shortcuts import render from django.urls import reverse from allauth import app_settings as allauth_settings from allauth.account import app_settings as account_settings from allauth.account.utils import user_display from allauth.core.exceptions import ImmediateHttpResponse from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.internal import flows from allauth.socialaccount.providers.base import AuthError def render_authentication_error( request, provider, error=AuthError.UNKNOWN, exception=None, extra_context=None, ): try: if allauth_settings.HEADLESS_ENABLED: from allauth.headless.socialaccount import internal internal.on_authentication_error( request, provider=provider, error=error, exception=exception, extra_context=extra_context, ) if extra_context is None: extra_context = {} get_adapter().on_authentication_error( request, provider, error=error, exception=exception, extra_context=extra_context, ) except ImmediateHttpResponse as e: return e.response if error == AuthError.CANCELLED: return HttpResponseRedirect(reverse("socialaccount_login_cancelled")) context = { "auth_error": { "provider": provider, "code": error, "exception": exception, } } context.update(extra_context) return render( request, "socialaccount/authentication_error." + account_settings.TEMPLATE_EXTENSION, context, ) def complete_social_login(request, sociallogin): if sociallogin.is_headless: from allauth.headless.socialaccount import internal return internal.complete_login(request, sociallogin) return flows.login.complete_login(request, sociallogin) def socialaccount_user_display(socialaccount): func = app_settings.SOCIALACCOUNT_STR if not func: return user_display(socialaccount.user) return func(socialaccount) django-allauth-65.0.2/allauth/socialaccount/internal/000077500000000000000000000000001467545753200226155ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/internal/__init__.py000066400000000000000000000000001467545753200247140ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/internal/flows/000077500000000000000000000000001467545753200237475ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/internal/flows/__init__.py000066400000000000000000000002661467545753200260640ustar00rootroot00000000000000from allauth.socialaccount.internal.flows import ( connect, email_authentication, login, signup, ) __all__ = ["connect", "login", "signup", "email_authentication"] django-allauth-65.0.2/allauth/socialaccount/internal/flows/connect.py000066400000000000000000000115061467545753200257550ustar00rootroot00000000000000from django.contrib import messages from django.core.exceptions import PermissionDenied, ValidationError from django.http import HttpResponseRedirect from allauth import app_settings as allauth_settings from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal import flows from allauth.account.models import EmailAddress from allauth.core.exceptions import ReauthenticationRequired from allauth.socialaccount import signals from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialAccount, SocialLogin def validate_disconnect(request, account): """ Validate whether or not the socialaccount account can be safely disconnected. """ accounts = SocialAccount.objects.filter(user_id=account.user_id) is_last = not accounts.exclude(pk=account.pk).exists() adapter = get_adapter() if is_last: if allauth_settings.SOCIALACCOUNT_ONLY: raise adapter.validation_error("disconnect_last") # No usable password would render the local account unusable if not account.user.has_usable_password(): raise adapter.validation_error("no_password") # No email address, no password reset if ( account_settings.EMAIL_VERIFICATION == account_settings.EmailVerificationMethod.MANDATORY ): if not EmailAddress.objects.filter( user=account.user, verified=True ).exists(): raise adapter.validation_error("no_verified_email") adapter.validate_disconnect(account, accounts) def disconnect(request, account): if account_settings.REAUTHENTICATION_REQUIRED: flows.reauthentication.raise_if_reauthentication_required(request) get_account_adapter().add_message( request, messages.INFO, "socialaccount/messages/account_disconnected.txt", ) provider = account.get_provider() account.delete() signals.social_account_removed.send( sender=SocialAccount, request=request, socialaccount=account ) get_adapter().send_notification_mail( "socialaccount/email/account_disconnected", request.user, context={ "account": account, "provider": provider, }, ) def resume_connect(request, serialized_state): sociallogin = SocialLogin.deserialize(serialized_state) return connect(request, sociallogin) def connect(request, sociallogin): try: ok, action, message = do_connect(request, sociallogin) except PermissionDenied: # This should not happen. Simply redirect to the connections # view (which has a login required) connect_redirect_url = get_adapter().get_connect_redirect_url( request, sociallogin.account ) return HttpResponseRedirect(connect_redirect_url) except ReauthenticationRequired: return flows.reauthentication.stash_and_reauthenticate( request, sociallogin.serialize(), "allauth.socialaccount.internal.flows.connect.resume_connect", ) except ValidationError: ok, action, message = ( False, None, "socialaccount/messages/account_connected_other.txt", ) level = messages.INFO if ok else messages.ERROR default_next = get_adapter().get_connect_redirect_url(request, sociallogin.account) next_url = sociallogin.get_redirect_url(request) or default_next get_account_adapter(request).add_message( request, level, message, message_context={"sociallogin": sociallogin, "action": action}, ) return HttpResponseRedirect(next_url) def do_connect(request, sociallogin): if request.user.is_anonymous: raise PermissionDenied() if account_settings.REAUTHENTICATION_REQUIRED: flows.reauthentication.raise_if_reauthentication_required(request) message = "socialaccount/messages/account_connected.txt" action = None ok = True if sociallogin.is_existing: if sociallogin.user != request.user: # Social account of other user. For now, this scenario # is not supported. Issue is that one cannot simply # remove the social account from the other user, as # that may render the account unusable. raise get_adapter().validation_error("connected_other") elif not sociallogin.account._state.adding: action = "updated" message = "socialaccount/messages/account_connected_updated.txt" else: action = "added" sociallogin.connect(request, request.user) else: # New account, let's connect action = "added" sociallogin.connect(request, request.user) return ok, action, message django-allauth-65.0.2/allauth/socialaccount/internal/flows/email_authentication.py000066400000000000000000000027221467545753200305120ustar00rootroot00000000000000from allauth import app_settings as allauth_settings from allauth.account.models import EmailAddress def wipe_password(request, user, email: str): """ Consider a scenario where an attacker signs up for an account using the email address of a victim. Obviously, the email address cannot be verified, yet the attacker -- knowing the password -- can wait until the victim appears. When the victim signs in using email authentication, it is not obvious that the victim is signing into an account that was not created by the victim. As a result, both the attacker and the victim now have access to the account. To prevent this, we wipe the password of the account in case the email address was not verified, effectively locking out the attacker. """ try: address = EmailAddress.objects.get_for_user(user, email) except EmailAddress.DoesNotExist: address = None if address and address.verified: # Verified email address, no reason to worry. return if user.has_usable_password(): user.set_unusable_password() user.save(update_fields=["password"]) # Also wipe any other sessions (upstream integrators may hook up to the # ending of the sessions to trigger e.g. backchannel logout. if allauth_settings.USERSESSIONS_ENABLED: from allauth.usersessions.internal.flows.sessions import ( end_other_sessions, ) end_other_sessions(request, user) django-allauth-65.0.2/allauth/socialaccount/internal/flows/login.py000066400000000000000000000057741467545753200254460ustar00rootroot00000000000000from django.http import HttpResponseRedirect from django.shortcuts import render from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.utils import perform_login from allauth.core.exceptions import ( ImmediateHttpResponse, SignupClosedException, ) from allauth.socialaccount import app_settings, signals from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.internal.flows.connect import connect, do_connect from allauth.socialaccount.internal.flows.signup import ( clear_pending_signup, process_signup, ) from allauth.socialaccount.models import SocialLogin from allauth.socialaccount.providers.base import AuthProcess def _login(request, sociallogin): sociallogin._accept_login(request) record_authentication(request, sociallogin) return perform_login( request, sociallogin.user, email_verification=app_settings.EMAIL_VERIFICATION, redirect_url=sociallogin.get_redirect_url(request), signal_kwargs={"sociallogin": sociallogin}, ) def pre_social_login(request, sociallogin): clear_pending_signup(request) assert not sociallogin.is_existing sociallogin.lookup() get_adapter().pre_social_login(request, sociallogin) signals.pre_social_login.send( sender=SocialLogin, request=request, sociallogin=sociallogin ) def complete_login(request, sociallogin, raises=False): try: pre_social_login(request, sociallogin) process = sociallogin.state.get("process") if process == AuthProcess.REDIRECT: return _redirect(request, sociallogin) elif process == AuthProcess.CONNECT: if raises: do_connect(request, sociallogin) else: return connect(request, sociallogin) else: return _authenticate(request, sociallogin) except SignupClosedException: if raises: raise return render( request, "account/signup_closed." + account_settings.TEMPLATE_EXTENSION, ) except ImmediateHttpResponse as e: if raises: raise return e.response def _redirect(request, sociallogin): next_url = sociallogin.get_redirect_url(request) or "/" return HttpResponseRedirect(next_url) def _authenticate(request, sociallogin): if request.user.is_authenticated: get_account_adapter(request).logout(request) if sociallogin.is_existing: # Login existing user ret = _login(request, sociallogin) else: # New social user ret = process_signup(request, sociallogin) return ret def record_authentication(request, sociallogin): from allauth.account.internal.flows.login import record_authentication record_authentication( request, "socialaccount", **{ "provider": sociallogin.account.provider, "uid": sociallogin.account.uid, } ) django-allauth-65.0.2/allauth/socialaccount/internal/flows/signup.py000066400000000000000000000107571467545753200256400ustar00rootroot00000000000000from django.forms import ValidationError from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal.flows.manage_email import assess_unique_email from allauth.account.internal.flows.signup import ( complete_signup, prevent_enumeration, ) from allauth.account.utils import user_username from allauth.core.exceptions import SignupClosedException from allauth.core.internal.httpkit import headed_redirect_response from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialLogin def get_pending_signup(request): data = request.session.get("socialaccount_sociallogin") if data: return SocialLogin.deserialize(data) def redirect_to_signup(request, sociallogin): request.session["socialaccount_sociallogin"] = sociallogin.serialize() return headed_redirect_response("socialaccount_signup") def clear_pending_signup(request): request.session.pop("socialaccount_sociallogin", None) def signup_by_form(request, sociallogin, form): clear_pending_signup(request) user, resp = form.try_save(request) if not resp: resp = complete_social_signup(request, sociallogin) return resp def process_auto_signup(request, sociallogin): auto_signup = get_adapter().is_auto_signup_allowed(request, sociallogin) if not auto_signup: return False, None email = None if sociallogin.email_addresses: email = sociallogin.email_addresses[0].email # Let's check if auto_signup is really possible... if email: assessment = assess_unique_email(email) if assessment is True: # Auto signup is fine. pass elif assessment is False: # Oops, another user already has this address. We cannot simply # connect this social account to the existing user. Reason is # that the email address may not be verified, meaning, the user # may be a hacker that has added your email address to their # account in the hope that you fall in their trap. We cannot # check on 'email_address.verified' either, because # 'email_address' is not guaranteed to be verified. auto_signup = False # TODO: We redirect to signup form -- user will see email # address conflict only after posting whereas we detected it # here already. else: assert assessment is None # Prevent enumeration is properly turned on, meaning, we cannot # show the signup form to allow the user to input another email # address. Instead, we're going to send the user an email that # the account already exists, and on the outside make it appear # as if an email verification mail was sent. resp = prevent_enumeration(request, email) return False, resp elif app_settings.EMAIL_REQUIRED: # Nope, email is required and we don't have it yet... auto_signup = False return auto_signup, None def process_signup(request, sociallogin): if not get_adapter().is_open_for_signup(request, sociallogin): raise SignupClosedException() auto_signup, resp = process_auto_signup(request, sociallogin) if resp: return resp if not auto_signup: resp = redirect_to_signup(request, sociallogin) else: # Ok, auto signup it is, at least the email address is ok. # We still need to check the username though... if account_settings.USER_MODEL_USERNAME_FIELD: username = user_username(sociallogin.user) try: get_account_adapter(request).clean_username(username) except ValidationError: # This username is no good ... user_username(sociallogin.user, "") # TODO: This part contains a lot of duplication of logic # ("closed" rendering, create user, send email, in active # etc..) get_adapter().save_user(request, sociallogin, form=None) resp = complete_social_signup(request, sociallogin) return resp def complete_social_signup(request, sociallogin): return complete_signup( request, user=sociallogin.user, email_verification=app_settings.EMAIL_VERIFICATION, redirect_url=sociallogin.get_redirect_url(request), signal_kwargs={"sociallogin": sociallogin}, ) django-allauth-65.0.2/allauth/socialaccount/internal/jwtkit.py000066400000000000000000000055761467545753200245200ustar00rootroot00000000000000import json import time from django.core.cache import cache import jwt from cryptography.hazmat.backends import default_backend from cryptography.x509 import load_pem_x509_certificate from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error def lookup_kid_pem_x509_certificate(keys_data, kid): """ Looks up the key given keys data of the form: {"": "-----BEGIN CERTIFICATE-----\nCERTIFICATE"} """ key = keys_data.get(kid) if key: public_key = load_pem_x509_certificate( key.encode("utf8"), default_backend() ).public_key() return public_key def lookup_kid_jwk(keys_data, kid): """ Looks up the key given keys data of the form: { "keys": [ { "kty": "RSA", "kid": "W6WcOKB", "use": "sig", "alg": "RS256", "n": "2Zc5d0-zk....", "e": "AQAB" }] } """ for d in keys_data["keys"]: if d["kid"] == kid: public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(d)) return public_key def fetch_key(credential, keys_url, lookup): header = jwt.get_unverified_header(credential) # {'alg': 'RS256', 'kid': '0ad1fec78504f447bae65bcf5afaedb65eec9e81', 'typ': 'JWT'} kid = header["kid"] alg = header["alg"] response = get_adapter().get_requests_session().get(keys_url) response.raise_for_status() keys_data = response.json() key = lookup(keys_data, kid) if not key: raise OAuth2Error(f"Invalid 'kid': '{kid}'") return alg, key def verify_jti(data: dict) -> None: """ Put the JWT token on a blacklist to prevent replay attacks. """ iss = data.get("iss") exp = data.get("exp") jti = data.get("jti") if iss is None or exp is None or jti is None: return timeout = exp - time.time() key = f"jwt:iss={iss},jti={jti}" if not cache.add(key=key, value=True, timeout=timeout): raise OAuth2Error("token already used") def verify_and_decode( *, credential, keys_url, issuer, audience, lookup_kid, verify_signature=True ): try: if verify_signature: alg, key = fetch_key(credential, keys_url, lookup_kid) algorithms = [alg] else: key = "" algorithms = None data = jwt.decode( credential, key=key, options={ "verify_signature": verify_signature, "verify_iss": True, "verify_aud": True, "verify_exp": True, }, issuer=issuer, audience=audience, algorithms=algorithms, ) verify_jti(data) return data except jwt.PyJWTError as e: raise OAuth2Error("Invalid id_token") from e django-allauth-65.0.2/allauth/socialaccount/internal/statekit.py000066400000000000000000000037601467545753200250250ustar00rootroot00000000000000import time from typing import Any, Dict, Optional, Tuple from allauth.socialaccount.adapter import get_adapter STATE_ID_LENGTH = 16 MAX_STATES = 10 STATES_SESSION_KEY = "socialaccount_states" def get_oldest_state( states: Dict[str, Tuple[Dict[str, Any], float]], rev: bool = False ) -> Tuple[Optional[str], Optional[Dict[str, Any]]]: oldest_ts = None oldest_id = None oldest = None for state_id, state_ts in states.items(): ts = state_ts[1] if oldest_ts is None or ( (rev and ts > oldest_ts) or ((not rev) and oldest_ts > ts) ): oldest_ts = ts oldest_id = state_id oldest = state_ts[0] return oldest_id, oldest def gc_states(states: Dict[str, Tuple[Dict[str, Any], float]]): if len(states) > MAX_STATES: oldest_id, oldest = get_oldest_state(states) if oldest_id: del states[oldest_id] def get_states(request) -> Dict[str, Tuple[Dict[str, Any], float]]: states = request.session.get(STATES_SESSION_KEY) if not isinstance(states, dict): states = {} return states def stash_state(request, state: Dict[str, Any], state_id: Optional[str] = None) -> str: states = get_states(request) gc_states(states) if state_id is None: state_id = get_adapter().generate_state_param(state) states[state_id] = (state, time.time()) request.session[STATES_SESSION_KEY] = states return state_id def unstash_state(request, state_id: str) -> Optional[Dict[str, Any]]: state: Optional[Dict[str, Any]] = None states = get_states(request) state_ts = states.get(state_id) if state_ts is not None: state = state_ts[0] del states[state_id] request.session[STATES_SESSION_KEY] = states return state def unstash_last_state(request) -> Optional[Dict[str, Any]]: states = get_states(request) state_id, state = get_oldest_state(states, rev=True) if state_id: unstash_state(request, state_id) return state django-allauth-65.0.2/allauth/socialaccount/internal/tests/000077500000000000000000000000001467545753200237575ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/internal/tests/__init__.py000066400000000000000000000000001467545753200260560ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/internal/tests/test_jwtkit.py000066400000000000000000000021441467545753200267050ustar00rootroot00000000000000from datetime import timedelta from django.utils import timezone from allauth.socialaccount.internal.jwtkit import verify_and_decode from allauth.socialaccount.providers.apple.client import jwt_encode from allauth.socialaccount.providers.oauth2.client import OAuth2Error def test_verify_and_decode(enable_cache): now = timezone.now() payload = { "iss": "https://accounts.google.com", "azp": "client_id", "aud": "client_id", "sub": "108204268033311374519", "hd": "example.com", "locale": "en", "iat": now, "jti": "a4e9b64d5e31da48a2037216e4ba9a5f5f4f50a0", "exp": now + timedelta(hours=1), } id_token = jwt_encode(payload, "secret") for attempt in range(2): try: verify_and_decode( credential=id_token, keys_url="/", issuer=payload["iss"], audience=payload["aud"], lookup_kid=False, verify_signature=False, ) assert attempt == 0 except OAuth2Error: assert attempt == 1 django-allauth-65.0.2/allauth/socialaccount/internal/tests/test_statekit.py000066400000000000000000000030101467545753200272120ustar00rootroot00000000000000from allauth.socialaccount.internal import statekit def test_get_oldest_state(): states = { "new": [{"id": "new"}, 300], "mid": [{"id": "mid"}, 200], "old": [{"id": "old"}, 100], } state_id, state = statekit.get_oldest_state(states) assert state_id == "old" assert state["id"] == "old" def test_get_oldest_state_empty(): state_id, state = statekit.get_oldest_state({}) assert state_id is None assert state is None def test_gc_states(): states = {} for i in range(statekit.MAX_STATES + 1): states[f"state-{i}"] = [{"i": i}, 1000 + i] assert len(states) == statekit.MAX_STATES + 1 statekit.gc_states(states) assert len(states) == statekit.MAX_STATES assert "state-0" not in states def test_stashing(rf): request = rf.get("/") request.session = {} state_id = statekit.stash_state(request, {"foo": "bar"}) state2_id = statekit.stash_state(request, {"foo2": "bar2"}) state3_id = statekit.stash_state(request, {"foo3": "bar3"}) state = statekit.unstash_last_state(request) assert state == {"foo3": "bar3"} state = statekit.unstash_state(request, state3_id) assert state is None state = statekit.unstash_state(request, state2_id) assert state == {"foo2": "bar2"} state = statekit.unstash_state(request, state2_id) assert state is None state = statekit.unstash_state(request, state_id) assert state == {"foo": "bar"} state = statekit.unstash_state(request, state_id) assert state is None django-allauth-65.0.2/allauth/socialaccount/migrations/000077500000000000000000000000001467545753200231555ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/migrations/0001_initial.py000066400000000000000000000141741467545753200256270ustar00rootroot00000000000000from django.conf import settings from django.db import migrations, models from allauth import app_settings class Migration(migrations.Migration): dependencies = ( [ ("sites", "0001_initial"), ] if app_settings.SITES_ENABLED else [] ) + [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name="SocialAccount", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ( "provider", models.CharField( max_length=30, verbose_name="provider", ), ), ( "uid", models.CharField( max_length=getattr( settings, "SOCIALACCOUNT_UID_MAX_LENGTH", 191 ), verbose_name="uid", ), ), ( "last_login", models.DateTimeField(auto_now=True, verbose_name="last login"), ), ( "date_joined", models.DateTimeField(auto_now_add=True, verbose_name="date joined"), ), ( "extra_data", models.TextField(default="{}", verbose_name="extra data"), ), ( "user", models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE ), ), ], options={ "verbose_name": "social account", "verbose_name_plural": "social accounts", }, bases=(models.Model,), ), migrations.CreateModel( name="SocialApp", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ( "provider", models.CharField( max_length=30, verbose_name="provider", ), ), ("name", models.CharField(max_length=40, verbose_name="name")), ( "client_id", models.CharField( help_text="App ID, or consumer key", max_length=100, verbose_name="client id", ), ), ( "secret", models.CharField( help_text="API secret, client secret, or consumer secret", max_length=100, verbose_name="secret key", ), ), ( "key", models.CharField( help_text="Key", max_length=100, verbose_name="key", blank=True, ), ), ] + ( [ ("sites", models.ManyToManyField(to="sites.Site", blank=True)), ] if app_settings.SITES_ENABLED else [] ), options={ "verbose_name": "social application", "verbose_name_plural": "social applications", }, bases=(models.Model,), ), migrations.CreateModel( name="SocialToken", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ( "token", models.TextField( help_text='"oauth_token" (OAuth1) or access token (OAuth2)', verbose_name="token", ), ), ( "token_secret", models.TextField( help_text='"oauth_token_secret" (OAuth1) or refresh token (OAuth2)', verbose_name="token secret", blank=True, ), ), ( "expires_at", models.DateTimeField( null=True, verbose_name="expires at", blank=True ), ), ( "account", models.ForeignKey( to="socialaccount.SocialAccount", on_delete=models.CASCADE, ), ), ( "app", models.ForeignKey( to="socialaccount.SocialApp", on_delete=models.CASCADE ), ), ], options={ "verbose_name": "social application token", "verbose_name_plural": "social application tokens", }, bases=(models.Model,), ), migrations.AlterUniqueTogether( name="socialtoken", unique_together=set([("app", "account")]), ), migrations.AlterUniqueTogether( name="socialaccount", unique_together=set([("provider", "uid")]), ), ] django-allauth-65.0.2/allauth/socialaccount/migrations/0002_token_max_lengths.py000066400000000000000000000024741467545753200277100ustar00rootroot00000000000000from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("socialaccount", "0001_initial"), ] operations = [ migrations.AlterField( model_name="socialaccount", name="uid", field=models.CharField( max_length=getattr(settings, "SOCIALACCOUNT_UID_MAX_LENGTH", 191), verbose_name="uid", ), ), migrations.AlterField( model_name="socialapp", name="client_id", field=models.CharField( help_text="App ID, or consumer key", max_length=191, verbose_name="client id", ), ), migrations.AlterField( model_name="socialapp", name="key", field=models.CharField( help_text="Key", max_length=191, verbose_name="key", blank=True ), ), migrations.AlterField( model_name="socialapp", name="secret", field=models.CharField( help_text="API secret, client secret, or consumer secret", max_length=191, verbose_name="secret key", blank=True, ), ), ] django-allauth-65.0.2/allauth/socialaccount/migrations/0003_extra_data_default_dict.py000066400000000000000000000006351467545753200310200ustar00rootroot00000000000000from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("socialaccount", "0002_token_max_lengths"), ] operations = [ migrations.AlterField( model_name="socialaccount", name="extra_data", field=models.TextField(default="{}", verbose_name="extra data"), preserve_default=True, ), ] django-allauth-65.0.2/allauth/socialaccount/migrations/0004_app_provider_id_settings.py000066400000000000000000000014751467545753200312670ustar00rootroot00000000000000# Generated by Django 3.2.19 on 2023-06-30 13:16 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("socialaccount", "0003_extra_data_default_dict"), ] operations = [ migrations.AddField( model_name="socialapp", name="provider_id", field=models.CharField( blank=True, max_length=200, verbose_name="provider ID" ), ), migrations.AddField( model_name="socialapp", name="settings", field=models.JSONField(blank=True, default=dict), ), migrations.AlterField( model_name="socialaccount", name="provider", field=models.CharField(max_length=200, verbose_name="provider"), ), ] django-allauth-65.0.2/allauth/socialaccount/migrations/0005_socialtoken_nullable_app.py000066400000000000000000000011251467545753200312230ustar00rootroot00000000000000# Generated by Django 3.2.20 on 2023-09-03 19:46 import django.db.models.deletion from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("socialaccount", "0004_app_provider_id_settings"), ] operations = [ migrations.AlterField( model_name="socialtoken", name="app", field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to="socialaccount.socialapp", ), ), ] django-allauth-65.0.2/allauth/socialaccount/migrations/0006_alter_socialaccount_extra_data.py000066400000000000000000000006631467545753200324130ustar00rootroot00000000000000# Generated by Django 3.2.20 on 2023-10-11 09:23 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("socialaccount", "0005_socialtoken_nullable_app"), ] operations = [ migrations.AlterField( model_name="socialaccount", name="extra_data", field=models.JSONField(default=dict, verbose_name="extra data"), ), ] django-allauth-65.0.2/allauth/socialaccount/migrations/__init__.py000066400000000000000000000000001467545753200252540ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/models.py000066400000000000000000000352211467545753200226410ustar00rootroot00000000000000from typing import Any, Dict, List, Optional from django.conf import settings from django.contrib.auth import authenticate, get_user_model from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.db import models from django.utils.translation import gettext_lazy as _ import allauth.app_settings from allauth import app_settings as allauth_settings from allauth.account.models import EmailAddress from allauth.account.utils import ( filter_users_by_email, get_next_redirect_url, setup_user_email, ) from allauth.core import context from allauth.socialaccount import app_settings, providers, signals from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.internal import statekit from allauth.utils import get_request_param if not allauth_settings.SOCIALACCOUNT_ENABLED: raise ImproperlyConfigured( "allauth.socialaccount not installed, yet its models are imported." ) class SocialAppManager(models.Manager): def on_site(self, request): if allauth.app_settings.SITES_ENABLED: site = get_current_site(request) return self.filter(sites__id=site.id) return self.all() class SocialApp(models.Model): objects = SocialAppManager() # The provider type, e.g. "google", "telegram", "saml". provider = models.CharField( verbose_name=_("provider"), max_length=30, ) # For providers that support subproviders, such as OpenID Connect and SAML, # this ID identifies that instance. SocialAccount's originating from app # will have their `provider` field set to the `provider_id` if available, # else `provider`. provider_id = models.CharField( verbose_name=_("provider ID"), max_length=200, blank=True, ) name = models.CharField(verbose_name=_("name"), max_length=40) client_id = models.CharField( verbose_name=_("client id"), max_length=191, help_text=_("App ID, or consumer key"), ) secret = models.CharField( verbose_name=_("secret key"), max_length=191, blank=True, help_text=_("API secret, client secret, or consumer secret"), ) key = models.CharField( verbose_name=_("key"), max_length=191, blank=True, help_text=_("Key") ) settings = models.JSONField(default=dict, blank=True) if allauth.app_settings.SITES_ENABLED: # Most apps can be used across multiple domains, therefore we use # a ManyToManyField. Note that Facebook requires an app per domain # (unless the domains share a common base name). # blank=True allows for disabling apps without removing them sites = models.ManyToManyField("sites.Site", blank=True) # type: ignore[var-annotated] class Meta: verbose_name = _("social application") verbose_name_plural = _("social applications") def __str__(self): return self.name def get_provider(self, request): provider_class = providers.registry.get_class(self.provider) return provider_class(request=request, app=self) class SocialAccount(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) # Given a `SocialApp` from which this account originates, this field equals # the app's `app.provider_id` if available, `app.provider` otherwise. provider = models.CharField( verbose_name=_("provider"), max_length=200, ) # Just in case you're wondering if an OpenID identity URL is going # to fit in a 'uid': # # Ideally, URLField(max_length=1024, unique=True) would be used # for identity. However, MySQL has a max_length limitation of 191 # for URLField (in case of utf8mb4). How about # models.TextField(unique=True) then? Well, that won't work # either for MySQL due to another bug[1]. So the only way out # would be to drop the unique constraint, or switch to shorter # identity URLs. Opted for the latter, as [2] suggests that # identity URLs are supposed to be short anyway, at least for the # old spec. # # [1] http://code.djangoproject.com/ticket/2495. # [2] http://openid.net/specs/openid-authentication-1_1.html#limits uid = models.CharField( verbose_name=_("uid"), max_length=app_settings.UID_MAX_LENGTH ) last_login = models.DateTimeField(verbose_name=_("last login"), auto_now=True) date_joined = models.DateTimeField(verbose_name=_("date joined"), auto_now_add=True) extra_data = models.JSONField(verbose_name=_("extra data"), default=dict) class Meta: unique_together = ("provider", "uid") verbose_name = _("social account") verbose_name_plural = _("social accounts") def authenticate(self): return authenticate(account=self) def __str__(self): from .helpers import socialaccount_user_display return socialaccount_user_display(self) def get_profile_url(self): return self.get_provider_account().get_profile_url() def get_avatar_url(self): return self.get_provider_account().get_avatar_url() def get_provider(self, request=None): provider = getattr(self, "_provider", None) if provider: return provider adapter = get_adapter() provider = self._provider = adapter.get_provider( request or context.request, provider=self.provider ) return provider def get_provider_account(self): return self.get_provider().wrap_account(self) class SocialToken(models.Model): app = models.ForeignKey(SocialApp, on_delete=models.SET_NULL, blank=True, null=True) account = models.ForeignKey(SocialAccount, on_delete=models.CASCADE) token = models.TextField( verbose_name=_("token"), help_text=_('"oauth_token" (OAuth1) or access token (OAuth2)'), ) token_secret = models.TextField( blank=True, verbose_name=_("token secret"), help_text=_('"oauth_token_secret" (OAuth1) or refresh token (OAuth2)'), ) expires_at = models.DateTimeField( blank=True, null=True, verbose_name=_("expires at") ) class Meta: unique_together = ("app", "account") verbose_name = _("social application token") verbose_name_plural = _("social application tokens") def __str__(self): return "%s (%s)" % (self._meta.verbose_name, self.pk) class SocialLogin: """ Represents a social user that is in the process of being logged in. This consists of the following information: `account` (`SocialAccount` instance): The social account being logged in. Providers are not responsible for checking whether or not an account already exists or not. Therefore, a provider typically creates a new (unsaved) `SocialAccount` instance. The `User` instance pointed to by the account (`account.user`) may be prefilled by the provider for use as a starting point later on during the signup process. `token` (`SocialToken` instance): An optional access token token that results from performing a successful authentication handshake. `state` (`dict`): The state to be preserved during the authentication handshake. Note that this state may end up in the url -- do not put any secrets in here. It currently only contains the url to redirect to after login. `email_addresses` (list of `EmailAddress`): Optional list of email addresses retrieved from the provider. """ account: SocialAccount token: Optional[SocialToken] email_addresses: List[EmailAddress] state: Dict _did_authenticate_by_email: Optional[str] def __init__( self, user=None, account: Optional[SocialAccount] = None, token: Optional[SocialToken] = None, email_addresses: Optional[List[EmailAddress]] = None, ): if token: assert token.account is None or token.account == account self.token = token self.user = user if account: self.account = account self.email_addresses = email_addresses if email_addresses else [] self.state = {} def connect(self, request, user) -> None: self.user = user self.save(request, connect=True) signals.social_account_added.send( sender=SocialLogin, request=request, sociallogin=self ) get_adapter().send_notification_mail( "socialaccount/email/account_connected", self.user, context={ "account": self.account, "provider": self.account.get_provider(), }, ) @property def is_headless(self) -> bool: return bool(self.state.get("headless")) def serialize(self) -> Dict[str, Any]: serialize_instance = get_adapter().serialize_instance ret = dict( account=serialize_instance(self.account), user=serialize_instance(self.user), state=self.state, email_addresses=[serialize_instance(ea) for ea in self.email_addresses], ) if self.token: ret["token"] = serialize_instance(self.token) return ret @classmethod def deserialize(cls, data: Dict[str, Any]) -> "SocialLogin": deserialize_instance = get_adapter().deserialize_instance account = deserialize_instance(SocialAccount, data["account"]) user = deserialize_instance(get_user_model(), data["user"]) if "token" in data: token = deserialize_instance(SocialToken, data["token"]) else: token = None email_addresses = [] for ea in data["email_addresses"]: email_address = deserialize_instance(EmailAddress, ea) email_addresses.append(email_address) ret = cls() ret.token = token ret.account = account ret.user = user ret.email_addresses = email_addresses ret.state = data["state"] return ret def save(self, request, connect: bool = False) -> None: """ Saves a new account. Note that while the account is new, the user may be an existing one (when connecting accounts) """ user = self.user user.save() self.account.user = user self.account.save() if app_settings.STORE_TOKENS and self.token: self.token.account = self.account self.token.save() if connect: # TODO: Add any new email addresses automatically? pass else: setup_user_email(request, user, self.email_addresses) @property def is_existing(self) -> bool: """When `False`, this social login represents a temporary account, not yet backed by a database record. """ if self.user.pk is None: return False return get_user_model().objects.filter(pk=self.user.pk).exists() def lookup(self) -> None: """Look up the existing local user account to which this social login points, if any. """ self._did_authenticate_by_email = None if not self._lookup_by_socialaccount(): self._lookup_by_email() def _lookup_by_socialaccount(self) -> bool: assert not self.is_existing try: a = SocialAccount.objects.get( provider=self.account.provider, uid=self.account.uid ) # Update account a.extra_data = self.account.extra_data self.account = a self.user = self.account.user a.save() signals.social_account_updated.send( sender=SocialLogin, request=context.request, sociallogin=self ) self._store_token() return True except SocialAccount.DoesNotExist: return False def _store_token(self) -> None: # Update token if not app_settings.STORE_TOKENS or not self.token: return assert not self.token.pk app = self.token.app if app and not app.pk: # If the app is not stored in the db, leave the FK empty. app = None try: t = SocialToken.objects.get(account=self.account, app=app) t.token = self.token.token if self.token.token_secret: # only update the refresh token if we got one # many oauth2 providers do not resend the refresh token t.token_secret = self.token.token_secret t.expires_at = self.token.expires_at t.save() self.token = t except SocialToken.DoesNotExist: self.token.account = self.account self.token.app = app self.token.save() def _lookup_by_email(self) -> None: emails = [e.email for e in self.email_addresses if e.verified] for email in emails: if not get_adapter().can_authenticate_by_email(self, email): continue users = filter_users_by_email(email, prefer_verified=True) if users: self.user = users[0] self._did_authenticate_by_email = email return def _accept_login(self, request) -> None: from allauth.socialaccount.internal.flows.email_authentication import ( wipe_password, ) if self._did_authenticate_by_email: wipe_password(request, self.user, self._did_authenticate_by_email) if app_settings.EMAIL_AUTHENTICATION_AUTO_CONNECT: self.connect(context.request, self.user) def get_redirect_url(self, request) -> Optional[str]: url = self.state.get("next") return url @classmethod def state_from_request(cls, request) -> Dict[str, Any]: """ TODO: Deprecated! To be integrated with provider.redirect() """ state = {} next_url = get_next_redirect_url(request) if next_url: state["next"] = next_url state["process"] = get_request_param(request, "process", "login") state["scope"] = get_request_param(request, "scope", "") state["auth_params"] = get_request_param(request, "auth_params", "") return state @classmethod def stash_state(cls, request, state: Optional[Dict[str, Any]] = None) -> str: if state is None: # Only for providers that don't support redirect() yet. state = cls.state_from_request(request) return statekit.stash_state(request, state) @classmethod def unstash_state(cls, request) -> Optional[Dict[str, Any]]: state = statekit.unstash_last_state(request) if state is None: raise PermissionDenied() return state django-allauth-65.0.2/allauth/socialaccount/providers/000077500000000000000000000000001467545753200230165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/__init__.py000066400000000000000000000037771467545753200251450ustar00rootroot00000000000000import importlib from collections import OrderedDict from django.apps import apps from django.conf import settings from allauth.utils import import_attribute class ProviderRegistry: def __init__(self): self.provider_map = OrderedDict() self.loaded = False def get_class_list(self): self.load() return list(self.provider_map.values()) def register(self, cls): self.provider_map[cls.id] = cls def get_class(self, id): return self.provider_map.get(id) def as_choices(self): self.load() for provider_cls in self.provider_map.values(): yield (provider_cls.id, provider_cls.name) def load(self): # TODO: Providers register with the provider registry when # loaded. Here, we build the URLs for all registered providers. So, we # really need to be sure all providers did register, which is why we're # forcefully importing the `provider` modules here. The overall # mechanism is way to magical and depends on the import order et al, so # all of this really needs to be revisited. if not self.loaded: for app_config in apps.get_app_configs(): try: module_name = app_config.name + ".provider" provider_module = importlib.import_module(module_name) except ImportError as e: if e.name != module_name: raise else: provider_settings = getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) for cls in getattr(provider_module, "provider_classes", []): provider_class = provider_settings.get(cls.id, {}).get( "provider_class" ) if provider_class: cls = import_attribute(provider_class) self.register(cls) self.loaded = True registry = ProviderRegistry() django-allauth-65.0.2/allauth/socialaccount/providers/agave/000077500000000000000000000000001467545753200241015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/agave/__init__.py000066400000000000000000000000001467545753200262000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/agave/provider.py000066400000000000000000000020521467545753200263040ustar00rootroot00000000000000from allauth.socialaccount.providers.agave.views import AgaveAdapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class AgaveAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("web_url", "dflt") def get_avatar_url(self): return self.account.extra_data.get("avatar_url", "dflt") class AgaveProvider(OAuth2Provider): id = "agave" name = "Agave" account_class = AgaveAccount oauth2_adapter_class = AgaveAdapter def extract_uid(self, data): return str(data.get("create_time")) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username", ""), name=( (data.get("first_name", "") + " " + data.get("last_name", "")).strip() ), ) def get_default_scope(self): scope = ["PRODUCTION"] return scope provider_classes = [AgaveProvider] django-allauth-65.0.2/allauth/socialaccount/providers/agave/tests.py000066400000000000000000000015601467545753200256170ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import AgaveProvider class AgaveTests(OAuth2TestsMixin, TestCase): provider_id = AgaveProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "status": "success", "message": "User details retrieved successfully.", "version": "2.0.0-SNAPSHOT-rc3fad", "result": { "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "email": "jon@doe.edu", "phone": "", "mobile_phone": "", "status": "Active", "create_time": "20180322043812Z", "username": "jdoe" } } """, ) def get_expected_to_str(self): return "jdoe" django-allauth-65.0.2/allauth/socialaccount/providers/agave/urls.py000066400000000000000000000003101467545753200254320ustar00rootroot00000000000000from allauth.socialaccount.providers.agave.provider import AgaveProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(AgaveProvider) django-allauth-65.0.2/allauth/socialaccount/providers/agave/views.py000066400000000000000000000024561467545753200256170ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AgaveAdapter(OAuth2Adapter): provider_id = "agave" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("API_URL", "https://public.agaveapi.co") access_token_url = "{0}/token".format(provider_base_url) authorize_url = "{0}/authorize".format(provider_base_url) profile_url = "{0}/profiles/v2/me".format(provider_base_url) def complete_login(self, request, app, token, response): extra_data = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token}, headers={ "Authorization": "Bearer " + token.token, }, ) ) user_profile = ( extra_data.json()["result"] if "result" in extra_data.json() else {} ) return self.get_provider().sociallogin_from_response(request, user_profile) oauth2_login = OAuth2LoginView.adapter_view(AgaveAdapter) oauth2_callback = OAuth2CallbackView.adapter_view(AgaveAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/amazon/000077500000000000000000000000001467545753200243035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/amazon/__init__.py000066400000000000000000000000001467545753200264020ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/amazon/provider.py000066400000000000000000000017511467545753200265130ustar00rootroot00000000000000from allauth.socialaccount.providers.amazon.views import AmazonOAuth2Adapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class AmazonAccount(ProviderAccount): pass class AmazonProvider(OAuth2Provider): id = "amazon" name = "Amazon" account_class = AmazonAccount oauth2_adapter_class = AmazonOAuth2Adapter def get_default_scope(self): return ["profile"] def extract_uid(self, data): return str(data["user_id"]) def extract_common_fields(self, data): # Hackish way of splitting the fullname. # Assumes no middlenames. name = data.get("name", "") first_name, last_name = name, "" if name and " " in name: first_name, last_name = name.split(" ", 1) return dict( email=data.get("email", ""), last_name=last_name, first_name=first_name ) provider_classes = [AmazonProvider] django-allauth-65.0.2/allauth/socialaccount/providers/amazon/tests.py000066400000000000000000000012151467545753200260160ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import AmazonProvider class AmazonTests(OAuth2TestsMixin, TestCase): provider_id = AmazonProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "Profile":{ "CustomerId":"amzn1.account.K2LI23KL2LK2", "Name":"John Doe", "PrimaryEmail":"johndoe@example.com" } }""", ) def get_expected_to_str(self): return "johndoe@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/amazon/urls.py000066400000000000000000000002461467545753200256440ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import AmazonProvider urlpatterns = default_urlpatterns(AmazonProvider) django-allauth-65.0.2/allauth/socialaccount/providers/amazon/views.py000066400000000000000000000022571467545753200260200ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AmazonOAuth2Adapter(OAuth2Adapter): provider_id = "amazon" access_token_url = "https://api.amazon.com/auth/o2/token" authorize_url = "http://www.amazon.com/ap/oa" profile_url = "https://api.amazon.com/user/profile" def complete_login(self, request, app, token, **kwargs): response = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) response.raise_for_status() extra_data = response.json() if "Profile" in extra_data: extra_data = { "user_id": extra_data["Profile"]["CustomerId"], "name": extra_data["Profile"]["Name"], "email": extra_data["Profile"]["PrimaryEmail"], } return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(AmazonOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(AmazonOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/000077500000000000000000000000001467545753200260255ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/__init__.py000066400000000000000000000000001467545753200301240ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/provider.py000066400000000000000000000042361467545753200302360ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.amazon_cognito.utils import ( convert_to_python_bool_if_value_is_json_string_bool, ) from allauth.socialaccount.providers.amazon_cognito.views import ( AmazonCognitoOAuth2Adapter, ) from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class AmazonCognitoAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("picture") def get_profile_url(self): return self.account.extra_data.get("profile") class AmazonCognitoProvider(OAuth2Provider): id = "amazon_cognito" name = "Amazon Cognito" account_class = AmazonCognitoAccount oauth2_adapter_class = AmazonCognitoOAuth2Adapter def extract_uid(self, data): return str(data["sub"]) def extract_common_fields(self, data): return { "email": data.get("email"), "first_name": data.get("given_name"), "last_name": data.get("family_name"), } def get_default_scope(self): return ["openid", "profile", "email"] def extract_email_addresses(self, data): email = data.get("email") verified = convert_to_python_bool_if_value_is_json_string_bool( data.get("email_verified", False) ) return ( [EmailAddress(email=email, verified=verified, primary=True)] if email else [] ) def extract_extra_data(self, data): ret = dict(data) phone_number_verified = data.get("phone_number_verified") if phone_number_verified is not None: ret["phone_number_verified"] = ( convert_to_python_bool_if_value_is_json_string_bool( "phone_number_verified" ) ) return ret @classmethod def get_slug(cls): # IMPORTANT: Amazon Cognito does not support `_` characters # as part of their redirect URI. return super(AmazonCognitoProvider, cls).get_slug().replace("_", "-") provider_classes = [AmazonCognitoProvider] django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/tests.py000066400000000000000000000052461467545753200275500ustar00rootroot00000000000000import json from django.test import override_settings import pytest from allauth.account.models import EmailAddress from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.amazon_cognito.provider import ( AmazonCognitoProvider, ) from allauth.socialaccount.providers.amazon_cognito.utils import ( convert_to_python_bool_if_value_is_json_string_bool, ) from allauth.socialaccount.providers.amazon_cognito.views import ( AmazonCognitoOAuth2Adapter, ) from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase def _get_mocked_claims(): return { "sub": "4993b410-8a1b-4c36-b843-a9c1a697e6b7", "given_name": "John", "family_name": "Doe", "email": "jdoe@example.com", "username": "johndoe", } @override_settings( SOCIALACCOUNT_PROVIDERS={ "amazon_cognito": {"DOMAIN": "https://domain.auth.us-east-1.amazoncognito.com"} } ) class AmazonCognitoTestCase(OAuth2TestsMixin, TestCase): provider_id = AmazonCognitoProvider.id def get_mocked_response(self): mocked_payload = json.dumps(_get_mocked_claims()) return MockedResponse(status_code=200, content=mocked_payload) def get_expected_to_str(self): return "johndoe" @override_settings(SOCIALACCOUNT_PROVIDERS={"amazon_cognito": {}}) def test_oauth2_adapter_raises_if_domain_settings_is_missing( self, ): mocked_response = self.get_mocked_response() with self.assertRaises( ValueError, msg=AmazonCognitoOAuth2Adapter.DOMAIN_KEY_MISSING_ERROR, ): self.login(mocked_response) def test_saves_email_as_verified_if_email_is_verified_in_cognito( self, ): mocked_claims = _get_mocked_claims() mocked_claims["email_verified"] = True mocked_payload = json.dumps(mocked_claims) mocked_response = MockedResponse(status_code=200, content=mocked_payload) self.login(mocked_response) user_id = SocialAccount.objects.get(uid=mocked_claims["sub"]).user_id email_address = EmailAddress.objects.get(user_id=user_id) self.assertEqual(email_address.email, mocked_claims["email"]) self.assertTrue(email_address.verified) def test_provider_slug_replaces_underscores_with_hyphens(self): self.assertTrue("_" not in self.provider.get_slug()) @pytest.mark.parametrize( "input,output", [ (True, True), ("true", True), ("false", False), (False, False), ], ) def test_convert_bool(input, output): assert convert_to_python_bool_if_value_is_json_string_bool(input) == output django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/urls.py000066400000000000000000000003521467545753200273640ustar00rootroot00000000000000from allauth.socialaccount.providers.amazon_cognito.provider import ( AmazonCognitoProvider, ) from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(AmazonCognitoProvider) django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/utils.py000066400000000000000000000002361467545753200275400ustar00rootroot00000000000000def convert_to_python_bool_if_value_is_json_string_bool(s): if s == "true": return True elif s == "false": return False return s django-allauth-65.0.2/allauth/socialaccount/providers/amazon_cognito/views.py000066400000000000000000000031431467545753200275350ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AmazonCognitoOAuth2Adapter(OAuth2Adapter): provider_id = "amazon_cognito" DOMAIN_KEY_MISSING_ERROR = ( '"DOMAIN" key is missing in Amazon Cognito configuration.' ) @property def settings(self): return app_settings.PROVIDERS.get(self.provider_id, {}) @property def domain(self): domain = self.settings.get("DOMAIN") if domain is None: raise ValueError(self.DOMAIN_KEY_MISSING_ERROR) return domain @property def access_token_url(self): return "{}/oauth2/token".format(self.domain) @property def authorize_url(self): return "{}/oauth2/authorize".format(self.domain) @property def profile_url(self): return "{}/oauth2/userInfo".format(self.domain) def complete_login(self, request, app, token: SocialToken, **kwargs): headers = { "Authorization": "Bearer {}".format(token.token), } extra_data = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data.raise_for_status() return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth2_login = OAuth2LoginView.adapter_view(AmazonCognitoOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(AmazonCognitoOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/angellist/000077500000000000000000000000001467545753200250005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/angellist/__init__.py000066400000000000000000000000001467545753200270770ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/angellist/provider.py000066400000000000000000000016531467545753200272110ustar00rootroot00000000000000from allauth.socialaccount.providers.angellist.views import ( AngelListOAuth2Adapter, ) from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class AngelListAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("angellist_url") def get_avatar_url(self): return self.account.extra_data.get("image") class AngelListProvider(OAuth2Provider): id = "angellist" name = "AngelList" account_class = AngelListAccount oauth2_adapter_class = AngelListOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("angellist_url").split("/")[-1], name=data.get("name"), ) provider_classes = [AngelListProvider] django-allauth-65.0.2/allauth/socialaccount/providers/angellist/tests.py000066400000000000000000000017111467545753200265140ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import AngelListProvider class AngelListTests(OAuth2TestsMixin, TestCase): provider_id = AngelListProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"name":"pennersr","id":424732,"bio":"","follower_count":0, "angellist_url":"https://angel.co/dsxtst", "image":"https://angel.co/images/shared/nopic.png", "email":"raymond.penners@example.com","blog_url":null, "online_bio_url":null,"twitter_url":"https://twitter.com/dsxtst", "facebook_url":null,"linkedin_url":null,"aboutme_url":null, "github_url":null,"dribbble_url":null,"behance_url":null, "what_ive_built":null,"locations":[],"roles":[],"skills":[], "investor":false,"scopes":["message","talent","dealflow","comment", "email"]} """, ) def get_expected_to_str(self): return "raymond.penners@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/angellist/urls.py000066400000000000000000000002541467545753200263400ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import AngelListProvider urlpatterns = default_urlpatterns(AngelListProvider) django-allauth-65.0.2/allauth/socialaccount/providers/angellist/views.py000066400000000000000000000016441467545753200265140ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AngelListOAuth2Adapter(OAuth2Adapter): provider_id = "angellist" access_token_url = "https://angel.co/api/oauth/token/" authorize_url = "https://angel.co/api/oauth/authorize/" profile_url = "https://api.angel.co/1/me/" supports_state = False def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(AngelListOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(AngelListOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/apple/000077500000000000000000000000001467545753200241175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/apple/__init__.py000066400000000000000000000000001467545753200262160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/apple/apple_session.py000066400000000000000000000003411467545753200273330ustar00rootroot00000000000000from allauth.socialaccount.sessions import LoginSession APPLE_SESSION_COOKIE_NAME = "apple-login-session" def get_apple_session(request): return LoginSession(request, "apple_login_session", APPLE_SESSION_COOKIE_NAME) django-allauth-65.0.2/allauth/socialaccount/providers/apple/client.py000066400000000000000000000065301467545753200257530ustar00rootroot00000000000000import time from urllib.parse import parse_qsl, quote, urlencode from django.core.exceptions import ImproperlyConfigured import jwt from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) def jwt_encode(*args, **kwargs): resp = jwt.encode(*args, **kwargs) if isinstance(resp, bytes): # For PyJWT <2 resp = resp.decode("utf-8") return resp class Scope: EMAIL = "email" NAME = "name" class AppleOAuth2Client(OAuth2Client): """ Custom client because `Sign In With Apple`: * requires `response_mode` field in redirect_url * requires special `client_secret` as JWT """ def generate_client_secret(self): """Create a JWT signed with an apple provided private key""" now = int(time.time()) app = get_adapter(self.request).get_app(self.request, "apple") if not app.key: raise ImproperlyConfigured("Apple 'key' missing") certificate_key = app.settings.get("certificate_key") if not certificate_key: raise ImproperlyConfigured("Apple 'certificate_key' missing") claims = { "iss": app.key, "aud": "https://appleid.apple.com", "sub": self.get_client_id(), "iat": now, "exp": now + 60 * 60, } headers = {"kid": self.consumer_secret, "alg": "ES256"} client_secret = jwt_encode( payload=claims, key=certificate_key, algorithm="ES256", headers=headers ) return client_secret def get_client_id(self): """We support multiple client_ids, but use the first one for api calls""" return self.consumer_key.split(",")[0] def get_access_token(self, code, pkce_code_verifier=None): url = self.access_token_url client_secret = self.generate_client_secret() data = { "client_id": self.get_client_id(), "code": code, "grant_type": "authorization_code", "redirect_uri": self.callback_url, "client_secret": client_secret, } if pkce_code_verifier: data["code_verifier"] = pkce_code_verifier self._strip_empty_keys(data) resp = ( get_adapter() .get_requests_session() .request(self.access_token_method, url, data=data, headers=self.headers) ) access_token = None if resp.status_code in [200, 201]: try: access_token = resp.json() except ValueError: access_token = dict(parse_qsl(resp.text)) if not access_token or "access_token" not in access_token: raise OAuth2Error("Error retrieving access token: %s" % resp.content) return access_token def get_redirect_url(self, authorization_url, scope, extra_params): scope = self.scope_delimiter.join(set(scope)) params = { "client_id": self.get_client_id(), "redirect_uri": self.callback_url, "response_mode": "form_post", "scope": scope, "response_type": "code id_token", } if self.state: params["state"] = self.state params.update(extra_params) return "%s?%s" % (authorization_url, urlencode(params, quote_via=quote)) django-allauth-65.0.2/allauth/socialaccount/providers/apple/provider.py000066400000000000000000000056261467545753200263340ustar00rootroot00000000000000import requests from allauth.account.models import EmailAddress from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.apple.views import AppleOAuth2Adapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class AppleAccount(ProviderAccount): def to_str(self): email = self.account.extra_data.get("email") if email and not email.lower().endswith("@privaterelay.appleid.com"): return email name = self.account.extra_data.get("name") or {} if name.get("firstName") or name.get("lastName"): full_name = f"{name['firstName'] or ''} {name['lastName'] or ''}" full_name = full_name.strip() if full_name: return full_name return super().to_str() class AppleProvider(OAuth2Provider): id = "apple" name = "Apple" account_class = AppleAccount oauth2_adapter_class = AppleOAuth2Adapter supports_token_authentication = True def extract_uid(self, data): return str(data["sub"]) def extract_common_fields(self, data): fields = {"email": data.get("email")} # If the name was provided name = data.get("name") if name: fields["first_name"] = name.get("firstName", "") fields["last_name"] = name.get("lastName", "") return fields def extract_email_addresses(self, data): ret = [] email = data.get("email") verified = data.get("email_verified") if isinstance(verified, str): verified = verified.lower() == "true" if email: ret.append( EmailAddress( email=email, verified=verified, primary=True, ) ) return ret def get_default_scope(self): scopes = ["name"] if QUERY_EMAIL: scopes.append("email") return scopes def verify_token(self, request, token): from allauth.socialaccount.providers.apple.views import ( AppleOAuth2Adapter, ) id_token = token.get("id_token") if not id_token: raise get_adapter().validation_error("invalid_token") try: identity_data = AppleOAuth2Adapter.get_verified_identity_data( self, id_token ) except (OAuth2Error, requests.RequestException) as e: raise get_adapter().validation_error("invalid_token") from e login = self.sociallogin_from_response(request, identity_data) return login def get_auds(self): return [aud.strip() for aud in self.app.client_id.split(",")] provider_classes = [AppleProvider] django-allauth-65.0.2/allauth/socialaccount/providers/apple/tests.py000066400000000000000000000226051467545753200256400ustar00rootroot00000000000000import json import time from importlib import import_module from urllib.parse import parse_qs, urlparse from django.conf import settings from django.test.utils import override_settings from django.urls import reverse from django.utils.http import urlencode import jwt from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .apple_session import APPLE_SESSION_COOKIE_NAME from .client import jwt_encode from .provider import AppleProvider # Generated on https://mkjwk.org/, used to sign and verify the apple id_token TESTING_JWT_KEYSET = { "p": ( "4ADzS5jKx_kdQihyOocVS0Qwwo7m0f7Ow56EadySJ-cmnwoHHF3AxgRaq-h-KwybSphv" "dc-X7NbS79-b9dumHKyt1MeVLAsDZD1a-uQCEneY1g9LsQkscNr7OggcpvMg5UUFwv6A" "kavu8cB0iyhNdha5_AWX27K5lNebvpaXEJ8" ), "kty": "RSA", "q": ( "yy5UvMjrvZyO1Os_nxXIugCa3NyWOkC8oMppPvr1Bl5AnF_xwXN2n9ozPd9Nb3Q3n-om" "NgLayyUxhwIjWDlI67Vbx-ESuff8ZEBKuTK0Gdmr4C_QU_j0gvvNMNJweSPxDdRmIUgO" "njTVNWmdqFTZs43jXAT4J519rgveNLAkGNE" ), "d": ( "riPuGIDde88WS03CVbo_mZ9toFWPyTxvuz8VInJ9S1ZxULo-hQWDBohWGYwvg8cgfXck" "cqWt5OBqNvPYdLgwb84uVi2JeEHmhcQSc_x0zfRTau5HVE2KdR-gWxQjPWoaBHeDVqwo" "PKaU2XYxa-gYDXcuSJWHz3BX13oInDEFCXr6VwiLiwLBFsb63EEHwyWXJbTpoar7AARW" "kz76qtngDkk4t9gk_Q0L1y1qf1GeWiAL7xWb-bdptma4-1ui-R2219-1ONEZ41v_jsIS" "_z8ooXmVCbUsHV4Z1UDpRvpORVE3u57WK3qXUdAtZsXjaIwkdItbDmL1jFUgefwfO91Y" "YQ" ), "e": "AQAB", "use": "sig", "kid": "testkey", "qi": ( "R0Hu4YmpHzw3SKWGYuAcAo6B97-JlN2fXiTjZ2g8eHGQX7LSoKEu0Hmu5hcBZYSgOuor" "IPsPUu3mNtx3pjLMOaJRk34VwcYu7h23ogEKGcPUt1c4tTotFDdw8WFptDOw4ow31Tml" "BPExLqzzGjJeQSNULB1bExuuhYMWx6wBXo8" ), "dp": ( "WBaHlnbjZ3hDVTzqjrGIYizSr-_aPUJitPKlR6wBncd8nJYo7bLAmB4mOewXkX5HozIG" "wuF78RsZoFLi1fAmhqgxQ7eopcU-9DBcksUPO4vkgmlJbrkYzNiQauW9vrllekOGXIQQ" "szhVoqP4MLEMpR-Sy9S3PyItcKbJDE3T4ik" ), "alg": "RS256", "dq": ( "Ar5kbIw2CsBzeVKX8FkF9eUOMk9URAMdyPoSw8P1zRk2vCXbiOY7Qttad8ptLEUgfytV" "SsNtGvMsoQsZWRak8nHnhGJ4s0QzB1OK7sdNgU_cL1HV-VxSSPaHhdJBrJEcrzggDPEB" "KYfDHU6Iz34d1nvjBxoWE8rfqJsGbCW4xxE" ), "n": ( "sclLPioUv4VOcOZWAKoRhcvwIH2jOhoHhSI_Cj5c5zSp7qaK8jCU6T7-GObsgrhpty-k" "26ZuqRdgu9d-62WO8OBGt1e0wxbTh128-nTTrOESHUlV_K1wpJmXOxNpJiybcgzZNbAm" "ACmsHfxZvN9bt7gKPXxf3-_zFAf12PbYMrOionAJ1N_4HxL7fz3xkr5C87Av06QNilIC" "-mA-4n9Eqw_R2DYNpE3RYMdWtwKqBwJC8qs3677RpG9vcc-yZ_97pEiytd2FBJ8uoTwH" "d3DHJB8UVgBSh1kMUpSdoM7HxVzKx732nx6Kusln79LrsfOzrXF4enkfKJYI40-uwT95" "zw" ), } # Mocked version of the test data from https://appleid.apple.com/auth/keys KEY_SERVER_RESP_JSON = json.dumps( { "keys": [ { "kty": TESTING_JWT_KEYSET["kty"], "kid": TESTING_JWT_KEYSET["kid"], "use": TESTING_JWT_KEYSET["use"], "alg": TESTING_JWT_KEYSET["alg"], "n": TESTING_JWT_KEYSET["n"], "e": TESTING_JWT_KEYSET["e"], } ] } ) def sign_id_token(payload): """ Sign a payload as apple normally would for the id_token. """ signing_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(TESTING_JWT_KEYSET)) return jwt_encode( payload, signing_key, algorithm="RS256", headers={"kid": TESTING_JWT_KEYSET["kid"]}, ) @override_settings( SOCIALACCOUNT_STORE_TOKENS=False, SOCIALACCOUNT_PROVIDERS={ "apple": { "APP": { "client_id": "app123id", "key": "apple", "secret": "dummy", "settings": { "certificate_key": """-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg2+Eybl8ojH4wB30C 3/iDkpsrxuPfs3DZ+3nHNghBOpmhRANCAAQSpo1eQ+EpNgQQyQVs/F27dkq3gvAI 28m95JEk26v64YAea5NTH56mru30RDqTKPgRVi5qRu3XGyqy3mdb8gMy -----END PRIVATE KEY----- """, }, } } }, ) class AppleTests(OAuth2TestsMixin, TestCase): provider_id = AppleProvider.id def get_apple_id_token_payload(self): now = int(time.time()) return { "iss": "https://appleid.apple.com", "aud": "app123id", # Matches `setup_app` "exp": now + 60 * 60, "iat": now, "sub": "000313.c9720f41e9434e18987a.1218", "at_hash": "CkaUPjk4MJinaAq6Z0tGUA", "email": "test@privaterelay.appleid.com", "email_verified": "true", "is_private_email": "true", "auth_time": 1234345345, # not converted automatically by pyjwt } def test_verify_token(self): id_token = sign_id_token(self.get_apple_id_token_payload()) with mocked_response(self.get_mocked_response()): sociallogin = self.provider.verify_token(None, {"id_token": id_token}) assert sociallogin.user.email == "test@privaterelay.appleid.com" def get_login_response_json(self, with_refresh_token=True): """ `with_refresh_token` is not optional for apple, so it's ignored. """ id_token = sign_id_token(self.get_apple_id_token_payload()) return json.dumps( { "access_token": "testac", # Matches OAuth2TestsMixin value "expires_in": 3600, "id_token": id_token, "refresh_token": "testrt", # Matches OAuth2TestsMixin value "token_type": "Bearer", } ) def get_mocked_response(self): """ Apple is unusual in that the `id_token` contains all the user info so no profile info request is made. However, it does need the public key verification, so this mocked response is the public key request in order to verify the authenticity of the id_token. """ return MockedResponse( 200, KEY_SERVER_RESP_JSON, {"content-type": "application/json"} ) def get_expected_to_str(self): return "A B" def get_complete_parameters(self, auth_request_params): """ Add apple specific response parameters which they include in the form_post response. https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms """ params = super().get_complete_parameters(auth_request_params) params.update( { "id_token": sign_id_token(self.get_apple_id_token_payload()), "user": json.dumps( { "email": "private@appleid.apple.com", "name": { "firstName": "A", "lastName": "B", }, } ), } ) return params def login(self, resp_mock, process="login", with_refresh_token=True): resp = self.client.post( reverse(self.provider.id + "_login") + "?" + urlencode(dict(process=process)) ) p = urlparse(resp["location"]) q = parse_qs(p.query) complete_url = reverse(self.provider.id + "_callback") self.assertGreater(q["redirect_uri"][0].find(complete_url), 0) response_json = self.get_login_response_json( with_refresh_token=with_refresh_token ) with mocked_response( MockedResponse(200, response_json, {"content-type": "application/json"}), resp_mock, ): resp = self.client.post( complete_url, data=self.get_complete_parameters(q), ) assert reverse("apple_finish_callback") in resp.url # Follow the redirect resp = self.client.get(resp.url) return resp def test_authentication_error(self): """Override base test because apple posts errors""" resp = self.client.post( reverse(self.provider.id + "_callback"), data={"error": "misc", "state": "testingstate123"}, ) assert reverse("apple_finish_callback") in resp.url # Follow the redirect resp = self.client.get(resp.url) self.assertTemplateUsed( resp, "socialaccount/authentication_error.%s" % getattr(settings, "ACCOUNT_TEMPLATE_EXTENSION", "html"), ) def test_apple_finish(self): resp = self.login(self.get_mocked_response()) # Check request generating the response finish_url = reverse("apple_finish_callback") self.assertEqual(resp.request["PATH_INFO"], finish_url) self.assertTrue("state" in resp.request["QUERY_STRING"]) self.assertTrue("code" in resp.request["QUERY_STRING"]) # Check have cookie containing apple session self.assertTrue(APPLE_SESSION_COOKIE_NAME in self.client.cookies) # Session should have been cleared apple_session_cookie = self.client.cookies.get(APPLE_SESSION_COOKIE_NAME) engine = import_module(settings.SESSION_ENGINE) SessionStore = engine.SessionStore apple_login_session = SessionStore(apple_session_cookie.value) self.assertEqual(len(apple_login_session.keys()), 0) # Check cookie path was correctly set self.assertEqual(apple_session_cookie.get("path"), finish_url) django-allauth-65.0.2/allauth/socialaccount/providers/apple/urls.py000066400000000000000000000006161467545753200254610ustar00rootroot00000000000000from django.urls import path from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import AppleProvider from .views import oauth2_finish_login urlpatterns = default_urlpatterns(AppleProvider) urlpatterns += [ path( AppleProvider.get_slug() + "/login/callback/finish/", oauth2_finish_login, name="apple_finish_callback", ), ] django-allauth-65.0.2/allauth/socialaccount/providers/apple/views.py000066400000000000000000000122761467545753200256360ustar00rootroot00000000000000import json from datetime import timedelta from django.http import HttpResponseNotAllowed, HttpResponseRedirect from django.urls import reverse from django.utils import timezone from django.utils.http import urlencode from django.views.decorators.csrf import csrf_exempt from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.internal import jwtkit from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from allauth.utils import build_absolute_uri, get_request_param from .apple_session import get_apple_session from .client import AppleOAuth2Client class AppleOAuth2Adapter(OAuth2Adapter): client_class = AppleOAuth2Client provider_id = "apple" access_token_url = "https://appleid.apple.com/auth/token" authorize_url = "https://appleid.apple.com/auth/authorize" public_key_url = "https://appleid.apple.com/auth/keys" @classmethod def get_verified_identity_data(cls, provider, id_token): data = jwtkit.verify_and_decode( credential=id_token, keys_url=cls.public_key_url, issuer="https://appleid.apple.com", audience=provider.get_auds(), lookup_kid=jwtkit.lookup_kid_jwk, ) return data def parse_token(self, data): token = SocialToken( token=data["access_token"], ) token.token_secret = data.get("refresh_token", "") expires_in = data.get(self.expires_in_key) if expires_in: token.expires_at = timezone.now() + timedelta(seconds=int(expires_in)) # `user_data` is a big flat dictionary with the parsed JWT claims # access_tokens, and user info from the apple post. identity_data = AppleOAuth2Adapter.get_verified_identity_data( self.get_provider(), data["id_token"] ) token.user_data = {**data, **identity_data} return token def complete_login(self, request, app, token, **kwargs): extra_data = token.user_data login = self.get_provider().sociallogin_from_response( request=request, response=extra_data ) login.state["id_token"] = token.user_data # We can safely remove the apple login session now # Note: The cookie will remain, but it's set to delete on browser close get_apple_session(request).delete() return login def get_user_scope_data(self, request): user_scope_data = request.apple_login_session.get("user", "") try: return json.loads(user_scope_data) except json.JSONDecodeError: # We do not care much about user scope data as it maybe blank # so return blank dictionary instead return {} def get_access_token_data(self, request, app, client, pkce_code_verifier=None): """We need to gather the info from the apple specific login""" apple_session = get_apple_session(request) # Exchange `code` code = get_request_param(request, "code") access_token_data = client.get_access_token( code, pkce_code_verifier=pkce_code_verifier ) id_token = access_token_data.get("id_token", None) # In case of missing id_token in access_token_data if id_token is None: id_token = apple_session.store.get("id_token") return { **access_token_data, **self.get_user_scope_data(request), "id_token": id_token, } @csrf_exempt @login_not_required def apple_post_callback(request, finish_endpoint_name="apple_finish_callback"): """ Apple uses a `form_post` response type, which due to CORS/Samesite-cookie rules means this request cannot access the request since the session cookie is unavailable. We work around this by storing the apple response in a separate, temporary session and redirecting to a more normal oauth flow. args: finish_endpoint_name (str): The name of a defined URL, which can be overridden in your url configuration if you have more than one callback endpoint. """ if request.method != "POST": return HttpResponseNotAllowed(["POST"]) apple_session = get_apple_session(request) # Add regular OAuth2 params to the URL - reduces the overrides required keys_to_put_in_url = ["code", "state", "error"] url_params = {} for key in keys_to_put_in_url: value = get_request_param(request, key, "") if value: url_params[key] = value # Add other params to the apple_login_session keys_to_save_to_session = ["user", "id_token"] for key in keys_to_save_to_session: apple_session.store[key] = get_request_param(request, key, "") url = build_absolute_uri(request, reverse(finish_endpoint_name)) response = HttpResponseRedirect( "{url}?{query}".format(url=url, query=urlencode(url_params)) ) apple_session.save(response) return response oauth2_login = OAuth2LoginView.adapter_view(AppleOAuth2Adapter) oauth2_callback = apple_post_callback oauth2_finish_login = OAuth2CallbackView.adapter_view(AppleOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/asana/000077500000000000000000000000001467545753200241015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/asana/__init__.py000066400000000000000000000000001467545753200262000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/asana/models.py000066400000000000000000000000001467545753200257240ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/asana/provider.py000066400000000000000000000011671467545753200263120ustar00rootroot00000000000000from allauth.socialaccount.providers.asana.views import AsanaOAuth2Adapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class AsanaAccount(ProviderAccount): pass class AsanaProvider(OAuth2Provider): id = "asana" name = "Asana" account_class = AsanaAccount oauth2_adapter_class = AsanaOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict(email=data.get("email"), name=data.get("name")) provider_classes = [AsanaProvider] django-allauth-65.0.2/allauth/socialaccount/providers/asana/tests.py000066400000000000000000000011341467545753200256140ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import AsanaProvider class AsanaTests(OAuth2TestsMixin, TestCase): provider_id = AsanaProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"data": {"photo": null, "workspaces": [{"id": 31337, "name": "example.com"}, {"id": 3133777, "name": "Personal Projects"}], "email": "test@example.com", "name": "Test Name", "id": 43748387}}""", ) def get_expected_to_str(self): return "test@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/asana/urls.py000066400000000000000000000002441467545753200254400ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import AsanaProvider urlpatterns = default_urlpatterns(AsanaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/asana/views.py000066400000000000000000000016211467545753200256100ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AsanaOAuth2Adapter(OAuth2Adapter): provider_id = "asana" access_token_url = "https://app.asana.com/-/oauth_token" authorize_url = "https://app.asana.com/-/oauth_authorize" profile_url = "https://app.asana.com/api/1.0/users/me" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json()["data"] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(AsanaOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(AsanaOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/atlassian/000077500000000000000000000000001467545753200247755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/atlassian/__init__.py000066400000000000000000000000001467545753200270740ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/atlassian/provider.py000066400000000000000000000020731467545753200272030ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from .views import AtlassianOAuth2Adapter class AtlassianAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("picture") class AtlassianProvider(OAuth2Provider): id = "atlassian" name = "Atlassian" account_class = AtlassianAccount oauth2_adapter_class = AtlassianOAuth2Adapter def extract_uid(self, data): return data["account_id"] def extract_common_fields(self, data): return { "email": data.get("email"), "name": data.get("name"), "username": data.get("nickname"), "email_verified": data.get("email_verified"), } def get_default_scope(self): return ["read:me"] def get_auth_params(self): params = super().get_auth_params() params.update({"audience": "api.atlassian.com", "prompt": "consent"}) return params provider_classes = [AtlassianProvider] django-allauth-65.0.2/allauth/socialaccount/providers/atlassian/tests.py000066400000000000000000000022731467545753200265150ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import AtlassianProvider class AtlassianTests(OAuth2TestsMixin, TestCase): provider_id = AtlassianProvider.id def get_mocked_response(self): response_data = """ { "account_type": "atlassian", "account_id": "112233aa-bb11-cc22-33dd-445566abcabc", "email": "mia@example.com", "email_verified": true, "name": "Mia Krystof", "picture": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/112233aa-bb11-cc22-33dd-445566abcabc/1234abcd-9876-54aa-33aa-1234dfsade9487ds", "account_status": "active", "nickname": "mkrystof", "zoneinfo": "Australia/Sydney", "locale": "en-US", "extended_profile": { "job_title": "Designer", "organization": "mia@example.com", "department": "Design team", "location": "Sydney" } }""" return MockedResponse(200, response_data) def get_expected_to_str(self): return "mia@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/atlassian/urls.py000066400000000000000000000002541467545753200263350ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import AtlassianProvider urlpatterns = default_urlpatterns(AtlassianProvider) django-allauth-65.0.2/allauth/socialaccount/providers/atlassian/views.py000066400000000000000000000020771467545753200265120ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AtlassianOAuth2Adapter(OAuth2Adapter): provider_id = "atlassian" access_token_url = "https://api.atlassian.com/oauth/token" authorize_url = "https://auth.atlassian.com/authorize" profile_url = "https://api.atlassian.com/me" def complete_login(self, request, app, token: SocialToken, **kwargs): headers = { "Authorization": f"Bearer {token.token}", "Accept": "application/json", } response = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) response.raise_for_status() data = response.json() return self.get_provider().sociallogin_from_response(request, data) oauth2_login = OAuth2LoginView.adapter_view(AtlassianOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(AtlassianOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/auth0/000077500000000000000000000000001467545753200240375ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/auth0/__init__.py000066400000000000000000000000001467545753200261360ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/auth0/provider.py000066400000000000000000000015411467545753200262440ustar00rootroot00000000000000from allauth.socialaccount.providers.auth0.views import Auth0OAuth2Adapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class Auth0Account(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("picture") class Auth0Provider(OAuth2Provider): id = "auth0" name = "Auth0" account_class = Auth0Account oauth2_adapter_class = Auth0OAuth2Adapter def get_default_scope(self): return ["openid", "profile", "email"] def extract_uid(self, data): return str(data["sub"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), name=data.get("name"), ) provider_classes = [Auth0Provider] django-allauth-65.0.2/allauth/socialaccount/providers/auth0/tests.py000066400000000000000000000013651467545753200255600ustar00rootroot00000000000000from allauth.socialaccount.providers.auth0.provider import Auth0Provider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class Auth0Tests(OAuth2TestsMixin, TestCase): provider_id = Auth0Provider.id def get_mocked_response(self): return MockedResponse( 200, """ { "picture": "https://secure.gravatar.com/avatar/123", "email": "mr.bob@your.Auth0.server.example.com", "id": 2, "sub": 2, "identities": [], "name": "Mr Bob" } """, ) def get_expected_to_str(self): return "mr.bob@your.Auth0.server.example.com" django-allauth-65.0.2/allauth/socialaccount/providers/auth0/urls.py000066400000000000000000000003101467545753200253700ustar00rootroot00000000000000from allauth.socialaccount.providers.auth0.provider import Auth0Provider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(Auth0Provider) django-allauth-65.0.2/allauth/socialaccount/providers/auth0/views.py000066400000000000000000000020461467545753200255500ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class Auth0OAuth2Adapter(OAuth2Adapter): provider_id = "auth0" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("AUTH0_URL") access_token_url = "{0}/oauth/token".format(provider_base_url) authorize_url = "{0}/authorize".format(provider_base_url) profile_url = "{0}/userinfo".format(provider_base_url) def complete_login(self, request, app, token, response): extra_data = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) .json() ) return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(Auth0OAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(Auth0OAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/authentiq/000077500000000000000000000000001467545753200250205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/authentiq/__init__.py000066400000000000000000000000001467545753200271170ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/authentiq/provider.py000066400000000000000000000057761467545753200272430ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount import app_settings from allauth.socialaccount.providers.authentiq.views import ( AuthentiqOAuth2Adapter, ) from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class Scope: NAME = "aq:name" EMAIL = "email" PHONE = "phone" ADDRESS = "address" LOCATION = "aq:location" PUSH = "aq:push" IDENTITY_CLAIMS = frozenset( [ "sub", "name", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "profile", "picture", "website", "email", "email_verified", "gender", "birthdate", "zoneinfo", "locale", "phone_number", "phone_number_verified", "address", "updated_at", "aq:location", ] ) class AuthentiqAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("profile") def get_avatar_url(self): return self.account.extra_data.get("picture") class AuthentiqProvider(OAuth2Provider): id = "authentiq" name = "Authentiq" account_class = AuthentiqAccount oauth2_adapter_class = AuthentiqOAuth2Adapter def get_scope_from_request(self, request): scope = set(super().get_scope_from_request(request)) scope.add("openid") if Scope.EMAIL in scope: modifiers = "" if app_settings.EMAIL_REQUIRED: modifiers += "r" if app_settings.EMAIL_VERIFICATION: modifiers += "s" if modifiers: scope.add(Scope.EMAIL + "~" + modifiers) scope.remove(Scope.EMAIL) return list(scope) def get_default_scope(self): scope = [Scope.NAME, Scope.PUSH] if app_settings.QUERY_EMAIL: scope.append(Scope.EMAIL) return scope def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["prompt"] = "select_account" return ret def extract_uid(self, data): return str(data["sub"]) def extract_common_fields(self, data): return dict( username=data.get("preferred_username", data.get("given_name")), email=data.get("email"), name=data.get("name"), first_name=data.get("given_name"), last_name=data.get("family_name"), ) def extract_extra_data(self, data): return {k: v for k, v in data.items() if k in IDENTITY_CLAIMS} def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("email_verified"): ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [AuthentiqProvider] django-allauth-65.0.2/allauth/socialaccount/providers/authentiq/tests.py000066400000000000000000000070331467545753200265370ustar00rootroot00000000000000import json from django.test.client import RequestFactory from django.test.utils import override_settings from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import AuthentiqProvider from .views import AuthentiqOAuth2Adapter class AuthentiqTests(OAuth2TestsMixin, TestCase): provider_id = AuthentiqProvider.id def get_mocked_response(self): return MockedResponse( 200, json.dumps( { "sub": "ZLARGMFT1M", "email": "jane@email.invalid", "email_verified": True, "given_name": "Jane", "family_name": "Doe", } ), ) def get_expected_to_str(self): return "jane@email.invalid" @override_settings( SOCIALACCOUNT_QUERY_EMAIL=False, ) def test_default_scopes_no_email(self): scopes = self.provider.get_default_scope() self.assertIn("aq:name", scopes) self.assertNotIn("email", scopes) @override_settings( SOCIALACCOUNT_QUERY_EMAIL=True, ) def test_default_scopes_email(self): scopes = self.provider.get_default_scope() self.assertIn("aq:name", scopes) self.assertIn("email", scopes) def test_scopes(self): request = RequestFactory().get(AuthentiqOAuth2Adapter.authorize_url) scopes = self.provider.get_scope_from_request(request) self.assertIn("openid", scopes) self.assertIn("aq:name", scopes) def test_dynamic_scopes(self): request = RequestFactory().get( AuthentiqOAuth2Adapter.authorize_url, dict(scope="foo") ) scopes = self.provider.get_scope_from_request(request) self.assertIn("openid", scopes) self.assertIn("aq:name", scopes) self.assertIn("foo", scopes) @override_settings( SOCIALACCOUNT_QUERY_EMAIL=True, SOCIALACCOUNT_EMAIL_REQUIRED=True, SOCIALACCOUNT_EMAIL_VERIFICATION=True, ) def test_scopes_required_verified_email(self): request = RequestFactory().get(AuthentiqOAuth2Adapter.authorize_url) scopes = self.provider.get_scope_from_request(request) self.assertIn("email~rs", scopes) self.assertNotIn("email", scopes) @override_settings( SOCIALACCOUNT_QUERY_EMAIL=True, SOCIALACCOUNT_EMAIL_REQUIRED=False, SOCIALACCOUNT_EMAIL_VERIFICATION=True, ) def test_scopes_optional_verified_email(self): request = RequestFactory().get(AuthentiqOAuth2Adapter.authorize_url) scopes = self.provider.get_scope_from_request(request) self.assertIn("email~s", scopes) self.assertNotIn("email", scopes) @override_settings( SOCIALACCOUNT_QUERY_EMAIL=True, SOCIALACCOUNT_EMAIL_REQUIRED=True, SOCIALACCOUNT_EMAIL_VERIFICATION=False, ) def test_scopes_required_email(self): request = RequestFactory().get(AuthentiqOAuth2Adapter.authorize_url) scopes = self.provider.get_scope_from_request(request) self.assertIn("email~r", scopes) self.assertNotIn("email", scopes) @override_settings( SOCIALACCOUNT_QUERY_EMAIL=True, SOCIALACCOUNT_EMAIL_REQUIRED=False, SOCIALACCOUNT_EMAIL_VERIFICATION=False, ) def test_scopes_optional_email(self): request = RequestFactory().get(AuthentiqOAuth2Adapter.authorize_url) scopes = self.provider.get_scope_from_request(request) self.assertIn("email", scopes) django-allauth-65.0.2/allauth/socialaccount/providers/authentiq/urls.py000066400000000000000000000002541467545753200263600ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import AuthentiqProvider urlpatterns = default_urlpatterns(AuthentiqProvider) django-allauth-65.0.2/allauth/socialaccount/providers/authentiq/views.py000066400000000000000000000023151467545753200265300ustar00rootroot00000000000000from urllib.parse import urljoin from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class AuthentiqOAuth2Adapter(OAuth2Adapter): provider_id = "authentiq" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_url = settings.get("PROVIDER_URL", "https://connect.authentiq.io/") if not provider_url.endswith("/"): provider_url += "/" access_token_url = urljoin(provider_url, "token") authorize_url = urljoin(provider_url, "authorize") profile_url = urljoin(provider_url, "userinfo") def complete_login(self, request, app, token, **kwargs): auth = {"Authorization": "Bearer " + token.token} resp = get_adapter().get_requests_session().get(self.profile_url, headers=auth) resp.raise_for_status() extra_data = resp.json() login = self.get_provider().sociallogin_from_response(request, extra_data) return login oauth2_login = OAuth2LoginView.adapter_view(AuthentiqOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(AuthentiqOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/baidu/000077500000000000000000000000001467545753200241025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/baidu/__init__.py000066400000000000000000000000001467545753200262010ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/baidu/provider.py000066400000000000000000000020111467545753200263000ustar00rootroot00000000000000from allauth.socialaccount.providers.baidu.views import BaiduOAuth2Adapter from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class BaiduAccount(ProviderAccount): def get_profile_url(self): return "http://www.baidu.com/p/" + self.account.extra_data.get("uname") def get_avatar_url(self): return ( "http://tb.himg.baidu.com/sys/portraitn/item/" + self.account.extra_data.get("portrait") ) def to_str(self): dflt = super(BaiduAccount, self).to_str() return self.account.extra_data.get("uname", dflt) class BaiduProvider(OAuth2Provider): id = "baidu" name = "Baidu" account_class = BaiduAccount oauth2_adapter_class = BaiduOAuth2Adapter def extract_uid(self, data): return data["uid"] def extract_common_fields(self, data): return dict(username=data.get("uid"), name=data.get("uname")) provider_classes = [BaiduProvider] django-allauth-65.0.2/allauth/socialaccount/providers/baidu/tests.py000066400000000000000000000007751467545753200256270ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import BaiduProvider class BaiduTests(OAuth2TestsMixin, TestCase): provider_id = BaiduProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"portrait": "78c0e9839de59bbde7859ccf43", "uname": "\u90dd\u56fd\u715c", "uid": "3225892368"}""", ) def get_expected_to_str(self): return "\u90dd\u56fd\u715c" django-allauth-65.0.2/allauth/socialaccount/providers/baidu/urls.py000066400000000000000000000002441467545753200254410ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import BaiduProvider urlpatterns = default_urlpatterns(BaiduProvider) django-allauth-65.0.2/allauth/socialaccount/providers/baidu/views.py000066400000000000000000000017101467545753200256100ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class BaiduOAuth2Adapter(OAuth2Adapter): provider_id = "baidu" access_token_url = "https://openapi.baidu.com/oauth/2.0/token" authorize_url = "https://openapi.baidu.com/oauth/2.0/authorize" profile_url = ( "https://openapi.baidu.com/rest/2.0/passport/users/getLoggedInUser" # noqa ) def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(BaiduOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(BaiduOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/base/000077500000000000000000000000001467545753200237305ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/base/__init__.py000066400000000000000000000002151467545753200260370ustar00rootroot00000000000000from .constants import AuthAction, AuthError, AuthProcess # noqa from .provider import Provider, ProviderAccount, ProviderException # noqa django-allauth-65.0.2/allauth/socialaccount/providers/base/constants.py000066400000000000000000000005421467545753200263170ustar00rootroot00000000000000class AuthProcess: LOGIN = "login" CONNECT = "connect" REDIRECT = "redirect" class AuthAction: AUTHENTICATE = "authenticate" REAUTHENTICATE = "reauthenticate" REREQUEST = "rerequest" class AuthError: UNKNOWN = "unknown" CANCELLED = "cancelled" # Cancelled on request of user DENIED = "denied" # Denied by server django-allauth-65.0.2/allauth/socialaccount/providers/base/provider.py000066400000000000000000000304371467545753200261430ustar00rootroot00000000000000from typing import Dict, Optional from django.core.exceptions import ImproperlyConfigured, PermissionDenied from allauth.account.utils import get_next_redirect_url, get_request_param from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.internal import statekit from allauth.socialaccount.providers.base.constants import AuthProcess class ProviderException(Exception): pass class Provider: name: str # Provided by subclasses id: str # Provided by subclasses slug: Optional[str] = None # Provided by subclasses uses_apps = True supports_redirect = False # Indicates whether or not this provider supports logging in by posting an # access/id-token. supports_token_authentication = False def __init__(self, request, app=None): self.request = request if self.uses_apps and app is None: raise ValueError("missing: app") self.app = app def __str__(self): return self.name @classmethod def get_slug(cls): return cls.slug or cls.id def get_login_url(self, request, next=None, **kwargs): """ Builds the URL to redirect to when initiating a login for this provider. """ raise NotImplementedError("get_login_url() for " + self.name) def redirect_from_request(self, request): kwargs = self.get_redirect_from_request_kwargs(request) return self.redirect(request, **kwargs) def get_redirect_from_request_kwargs(self, request): kwargs = {} next_url = get_next_redirect_url(request) if next_url: kwargs["next_url"] = next_url kwargs["process"] = get_request_param(request, "process", AuthProcess.LOGIN) return kwargs def redirect(self, request, process, next_url=None, data=None, **kwargs): """ Initiate a redirect to the provider. """ raise NotImplementedError() def verify_token(self, request, token): """ Verifies the token, returning a `SocialLogin` instance when valid. Raises a `ValidationError` otherwise. """ raise NotImplementedError() def media_js(self, request): """ Some providers may require extra scripts (e.g. a Facebook connect) """ return "" def wrap_account(self, social_account): return self.account_class(social_account) def get_settings(self): return app_settings.PROVIDERS.get(self.id, {}) def sociallogin_from_response(self, request, response): """ Instantiates and populates a `SocialLogin` model based on the data retrieved in `response`. The method does NOT save the model to the DB. Data for `SocialLogin` will be extracted from `response` with the help of the `.extract_uid()`, `.extract_extra_data()`, `.extract_common_fields()`, and `.extract_email_addresses()` methods. :param request: a Django `HttpRequest` object. :param response: object retrieved via the callback response of the social auth provider. :return: A populated instance of the `SocialLogin` model (unsaved). """ # NOTE: Avoid loading models at top due to registry boot... from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialAccount, SocialLogin adapter = get_adapter() uid = self.extract_uid(response) if not isinstance(uid, str): raise ValueError(f"uid must be a string: {repr(uid)}") if len(uid) > app_settings.UID_MAX_LENGTH: raise ImproperlyConfigured( f"SOCIALACCOUNT_UID_MAX_LENGTH too small (<{len(uid)})" ) if not uid: raise ValueError("uid must be a non-empty string") extra_data = self.extract_extra_data(response) common_fields = self.extract_common_fields(response) socialaccount = SocialAccount( extra_data=extra_data, uid=uid, provider=self.sub_id, ) email_addresses = self.extract_email_addresses(response) email = self.cleanup_email_addresses( common_fields.get("email"), email_addresses, email_verified=common_fields.get("email_verified"), ) if email: common_fields["email"] = email sociallogin = SocialLogin( account=socialaccount, email_addresses=email_addresses ) user = sociallogin.user = adapter.new_user(request, sociallogin) user.set_unusable_password() adapter.populate_user(request, sociallogin, common_fields) return sociallogin def extract_uid(self, data): """ Extracts the unique user ID from `data` """ raise NotImplementedError( "The provider must implement the `extract_uid()` method" ) def extract_extra_data(self, data): """ Extracts fields from `data` that will be stored in `SocialAccount`'s `extra_data` JSONField, such as email address, first name, last name, and phone number. :return: any JSON-serializable Python structure. """ return data def extract_common_fields(self, data): """ Extracts fields from `data` that will be used to populate the `User` model in the `SOCIALACCOUNT_ADAPTER`'s `populate_user()` method. For example: {'first_name': 'John'} :return: dictionary of key-value pairs. """ return {} def cleanup_email_addresses( self, email: Optional[str], addresses: list, email_verified: bool = False ) -> Optional[str]: # Avoid loading models before adapters have been registered. from allauth.account.models import EmailAddress # Move user.email over to EmailAddress if email and email.lower() not in [a.email.lower() for a in addresses]: addresses.insert( 0, EmailAddress(email=email, verified=bool(email_verified), primary=True), ) # Force verified emails adapter = get_adapter() for address in addresses: if adapter.is_email_verified(self, address.email): address.verified = True # Sort in order of importance (primary, verified...) addresses.sort(key=lambda a: (a.primary, a.verified, a.email), reverse=True) if not email and addresses: email = addresses[0].email return email def extract_email_addresses(self, data): """ For example: [EmailAddress(email='john@example.com', verified=True, primary=True)] """ return [] @classmethod def get_package(cls): pkg = getattr(cls, "package", None) if not pkg: pkg = cls.__module__.rpartition(".")[0] return pkg def stash_redirect_state( self, request, process, next_url=None, data=None, state_id=None, **kwargs ): """ Stashes state, returning a (random) state ID using which the state can be looked up later. Application specific state is stored separately from (core) allauth state such as `process` and `**kwargs`. """ state = {"process": process, "data": data, **kwargs} if next_url: state["next"] = next_url return statekit.stash_state(request, state, state_id=state_id) def unstash_redirect_state(self, request, state_id): state = statekit.unstash_state(request, state_id) if state is None: raise PermissionDenied() return state @property def sub_id(self) -> str: return ( (self.app.provider_id or self.app.provider) if self.uses_apps else self.id ) class ProviderAccount: def __init__(self, social_account): self.account = social_account def get_profile_url(self): return None def get_avatar_url(self): return None def get_brand(self): """ Returns a dict containing an id and name identifying the brand. Useful when displaying logos next to accounts in templates. For most providers, these are identical to the provider. For OpenID however, the brand can derived from the OpenID identity url. """ provider = self.account.get_provider() return dict(id=provider.id, name=provider.name) def __str__(self): return self.to_str() def get_user_data(self) -> Optional[Dict]: """Typically, the ``extra_data`` directly contains user related keys. For some providers, however, they are nested below a different key. In that case, you can override this method so that the base ``__str__()`` will still be able to find the data. """ ret = self.account.extra_data if not isinstance(ret, dict): ret = None return ret def to_str(self): """ Returns string representation of this social account. This is the unique identifier of the account, such as its username or its email address. It should be meaningful to human beings, which means a numeric ID number is rarely the appropriate representation here. Subclasses are meant to override this method. Users will see the string representation of their social accounts in the page rendered by the allauth.socialaccount.views.connections view. The following code did not use to work in the past due to py2 compatibility: class GoogleAccount(ProviderAccount): def __str__(self): dflt = super(GoogleAccount, self).__str__() return self.account.extra_data.get('name', dflt) So we have this method `to_str` that can be overridden in a conventional fashion, without having to worry about it. """ user_data = self.get_user_data() if user_data: combi_values = {} tbl = [ # Prefer username -- it's the most human recognizable & unique. ( None, [ "username", "userName", "user_name", "login", "handle", ], ), # Second best is email (None, ["email", "Email", "mail", "email_address"]), ( None, [ "name", "display_name", "displayName", "Display_Name", "nickname", ], ), # Use the full name (None, ["full_name", "fullName"]), # Alternatively, try to assemble a full name ourselves. ( "first_name", [ "first_name", "firstname", "firstName", "First_Name", "given_name", "givenName", ], ), ( "last_name", [ "last_name", "lastname", "lastName", "Last_Name", "family_name", "familyName", "surname", ], ), ] for store_as, variants in tbl: for key in variants: value = user_data.get(key) if isinstance(value, str): value = value.strip() if value and not store_as: return value combi_values[store_as] = value first_name = combi_values.get("first_name") or "" last_name = combi_values.get("last_name") or "" if first_name or last_name: return f"{first_name} {last_name}".strip() return self.get_brand()["name"] django-allauth-65.0.2/allauth/socialaccount/providers/base/utils.py000066400000000000000000000010111467545753200254330ustar00rootroot00000000000000from django.shortcuts import render from allauth.account import app_settings as account_app_settings from allauth.socialaccount import app_settings def respond_to_login_on_get(request, provider): if (not app_settings.LOGIN_ON_GET) and request.method == "GET": return render( request, "socialaccount/login." + account_app_settings.TEMPLATE_EXTENSION, { "provider": provider, "process": request.GET.get("process"), }, ) django-allauth-65.0.2/allauth/socialaccount/providers/base/views.py000066400000000000000000000013741467545753200254440ustar00rootroot00000000000000from django.http import Http404 from django.views import View from allauth import app_settings as allauth_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.base.utils import respond_to_login_on_get class BaseLoginView(View): provider_id: str # Set in subclasses def dispatch(self, request, *args, **kwargs): if allauth_settings.HEADLESS_ONLY: raise Http404 provider = self.get_provider() resp = respond_to_login_on_get(request, provider) if resp: return resp return provider.redirect_from_request(request) def get_provider(self): provider = get_adapter().get_provider(self.request, self.provider_id) return provider django-allauth-65.0.2/allauth/socialaccount/providers/basecamp/000077500000000000000000000000001467545753200245715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/basecamp/__init__.py000066400000000000000000000000001467545753200266700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/basecamp/provider.py000066400000000000000000000023701467545753200267770ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.basecamp.views import ( BasecampOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class BasecampAccount(ProviderAccount): def get_avatar_url(self): return None def get_user_data(self): return self.account.extra_data.get("identity", {}) class BasecampProvider(OAuth2Provider): id = "basecamp" name = "Basecamp" account_class = BasecampAccount oauth2_adapter_class = BasecampOAuth2Adapter def get_auth_params_from_request(self, request, action): data = super().get_auth_params_from_request(request, action) data["type"] = "web_server" return data def extract_uid(self, data): data = data["identity"] return str(data["id"]) def extract_common_fields(self, data): data = data["identity"] return dict( email=data.get("email_address"), username=data.get("email_address"), first_name=data.get("first_name"), last_name=data.get("last_name"), name="%s %s" % (data.get("first_name"), data.get("last_name")), ) provider_classes = [BasecampProvider] django-allauth-65.0.2/allauth/socialaccount/providers/basecamp/tests.py000066400000000000000000000026321467545753200263100ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import BasecampProvider class BasecampTests(OAuth2TestsMixin, TestCase): provider_id = BasecampProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "expires_at": "2012-03-22T16:56:48-05:00", "identity": { "id": 9999999, "first_name": "Jason Fried", "last_name": "Jason Fried", "email_address": "jason@example.com" }, "accounts": [ { "product": "bcx", "id": 88888888, "name": "Wayne Enterprises, Ltd.", "href": "https://basecamp.com/88888888/api/v1" }, { "product": "bcx", "id": 77777777, "name": "Veidt, Inc", "href": "https://basecamp.com/77777777/api/v1" }, { "product": "campfire", "id": 44444444, "name": "Acme Shipping Co.", "href": "https://acme4444444.campfirenow.com" } ] }""", ) def get_expected_to_str(self): return "jason@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/basecamp/urls.py000066400000000000000000000002521467545753200261270ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import BasecampProvider urlpatterns = default_urlpatterns(BasecampProvider) django-allauth-65.0.2/allauth/socialaccount/providers/basecamp/views.py000066400000000000000000000017721467545753200263070ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class BasecampOAuth2Adapter(OAuth2Adapter): provider_id = "basecamp" access_token_url = ( "https://launchpad.37signals.com/authorization/token?type=web_server" # noqa ) authorize_url = "https://launchpad.37signals.com/authorization/new" profile_url = "https://launchpad.37signals.com/authorization.json" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(BasecampOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(BasecampOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/000077500000000000000000000000001467545753200250005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/__init__.py000066400000000000000000000000001467545753200270770ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/models.py000066400000000000000000000000001467545753200266230ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/provider.py000066400000000000000000000020631467545753200272050ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.battlenet.views import ( BattleNetOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class BattleNetAccount(ProviderAccount): def to_str(self): battletag = self.account.extra_data.get("battletag") return battletag or super(BattleNetAccount, self).to_str() class BattleNetProvider(OAuth2Provider): id = "battlenet" name = "Battle.net" account_class = BattleNetAccount oauth2_adapter_class = BattleNetOAuth2Adapter def extract_uid(self, data): uid = str(data["id"]) if data.get("region") == "cn": # China is on a different account system. UIDs can clash with US. return uid + "-cn" return uid def extract_common_fields(self, data): return {"username": data.get("battletag")} def get_default_scope(self): # Optional scopes: "sc2.profile", "wow.profile" return [] provider_classes = [BattleNetProvider] django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/tests.py000066400000000000000000000045631467545753200265240ustar00rootroot00000000000000import json from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import BattleNetProvider from .views import _check_errors class BattleNetTests(OAuth2TestsMixin, TestCase): provider_id = BattleNetProvider.id _uid = 123456789 _battletag = "LuckyDragon#1953" def get_mocked_response(self): data = {"battletag": self._battletag, "id": self._uid} return MockedResponse(200, json.dumps(data)) def get_expected_to_str(self): return self._battletag def test_valid_response_no_battletag(self): data = {"id": 12345} response = MockedResponse(200, json.dumps(data)) self.assertEqual(_check_errors(response), data) def test_invalid_data(self): response = MockedResponse(200, json.dumps({})) with self.assertRaises(OAuth2Error): # No id, raises _check_errors(response) def test_profile_invalid_response(self): data = {"code": 403, "type": "Forbidden", "detail": "Account Inactive"} response = MockedResponse(401, json.dumps(data)) with self.assertRaises(OAuth2Error): # no id, 4xx code, raises _check_errors(response) def test_error_response(self): body = json.dumps({"error": "invalid_token"}) response = MockedResponse(400, body) with self.assertRaises(OAuth2Error): # no id, 4xx code, raises _check_errors(response) def test_service_not_found(self): response = MockedResponse(596, "

596 Service Not Found

") with self.assertRaises(OAuth2Error): # bad json, 5xx code, raises _check_errors(response) def test_invalid_response(self): response = MockedResponse(200, "invalid json data") with self.assertRaises(OAuth2Error): # bad json, raises _check_errors(response) def test_extra_data(self): self.login(self.get_mocked_response()) account = SocialAccount.objects.get(uid=str(self._uid)) self.assertEqual(account.extra_data["battletag"], self._battletag) self.assertEqual(account.extra_data["id"], self._uid) self.assertEqual(account.extra_data["region"], "us") django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/urls.py000066400000000000000000000002541467545753200263400ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import BattleNetProvider urlpatterns = default_urlpatterns(BattleNetProvider) django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/validators.py000066400000000000000000000001611467545753200275200ustar00rootroot00000000000000from django.core.validators import RegexValidator BattletagUsernameValidator = RegexValidator(r"^[\w.]+#\d+$") django-allauth-65.0.2/allauth/socialaccount/providers/battlenet/views.py000066400000000000000000000110621467545753200265070ustar00rootroot00000000000000""" OAuth2 Adapter for Battle.net Resources: * Battle.net OAuth2 documentation: https://dev.battle.net/docs/read/oauth * Battle.net API documentation: https://dev.battle.net/io-docs * Original announcement: https://us.battle.net/en/forum/topic/13979297799 * The Battle.net API forum: https://us.battle.net/en/forum/15051532/ """ from django.conf import settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class Region: APAC = "apac" CN = "cn" EU = "eu" KR = "kr" SEA = "sea" TW = "tw" US = "us" def _check_errors(response): try: data = response.json() except ValueError: # JSONDecodeError on py3 raise OAuth2Error("Invalid JSON from Battle.net API: %r" % (response.text)) if response.status_code >= 400 or "error" in data: # For errors, we expect the following format: # {"error": "error_name", "error_description": "Oops!"} # For example, if the token is not valid, we will get: # { # "error": "invalid_token", # "error_description": "Invalid access token: abcdef123456" # } # For the profile API, this may also look like the following: # {"code": 403, "type": "Forbidden", "detail": "Account Inactive"} error = data.get("error", "") or data.get("type", "") desc = data.get("error_description", "") or data.get("detail", "") raise OAuth2Error("Battle.net error: %s (%s)" % (error, desc)) # The expected output from the API follows this format: # {"id": 12345, "battletag": "Example#12345"} # The battletag is optional. if "id" not in data: # If the id is not present, the output is not usable (no UID) raise OAuth2Error("Invalid data from Battle.net API: %r" % (data)) return data class BattleNetOAuth2Adapter(OAuth2Adapter): """ OAuth2 adapter for Battle.net https://dev.battle.net/docs/read/oauth Region is set to us by default, but can be overridden with the `region` GET parameter when performing a login. Can be any of eu, us, kr, sea, tw or cn """ provider_id = "battlenet" valid_regions = ( Region.APAC, Region.CN, Region.EU, Region.KR, Region.SEA, Region.TW, Region.US, ) @property def battlenet_region(self): # Check by URI query parameter first. region = self.request.GET.get("region", "").lower() if region == Region.SEA: # South-East Asia uses the same region as US everywhere return Region.US if region in self.valid_regions: return region # Second, check the provider settings. region = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("battlenet", {}) .get("REGION", "us") ) if region in self.valid_regions: return region return Region.US @property def battlenet_base_url(self): region = self.battlenet_region if region == Region.CN: return "https://www.battlenet.com.cn" return "https://%s.battle.net" % (region) @property def access_token_url(self): return self.battlenet_base_url + "/oauth/token" @property def authorize_url(self): return self.battlenet_base_url + "/oauth/authorize" @property def profile_url(self): return self.battlenet_base_url + "/oauth/userinfo" def complete_login(self, request, app, token, **kwargs): params = {"access_token": token.token} response = ( get_adapter().get_requests_session().get(self.profile_url, params=params) ) data = _check_errors(response) # Add the region to the data so that we can have it in `extra_data`. data["region"] = self.battlenet_region return self.get_provider().sociallogin_from_response(request, data) def get_callback_url(self, request, app): r = super(BattleNetOAuth2Adapter, self).get_callback_url(request, app) region = request.GET.get("region", "").lower() # Pass the region down to the callback URL if we specified it if region and region in self.valid_regions: r += "?region=%s" % (region) return r oauth2_login = OAuth2LoginView.adapter_view(BattleNetOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(BattleNetOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/bitbucket_oauth2/000077500000000000000000000000001467545753200262545ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/bitbucket_oauth2/__init__.py000066400000000000000000000000001467545753200303530ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/bitbucket_oauth2/provider.py000066400000000000000000000020001467545753200304500ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.bitbucket_oauth2.views import ( BitbucketOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class BitbucketOAuth2Account(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("links", {}).get("html", {}).get("href") def get_avatar_url(self): return self.account.extra_data.get("links", {}).get("avatar", {}).get("href") class BitbucketOAuth2Provider(OAuth2Provider): id = "bitbucket_oauth2" name = "Bitbucket" account_class = BitbucketOAuth2Account oauth2_adapter_class = BitbucketOAuth2Adapter def extract_uid(self, data): return data["username"] def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), name=data.get("display_name"), ) provider_classes = [BitbucketOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/bitbucket_oauth2/tests.py000066400000000000000000000075501467545753200277770ustar00rootroot00000000000000from django.test.utils import override_settings from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import BitbucketOAuth2Provider @override_settings(SOCIALACCOUNT_QUERY_EMAIL=True, SOCIALACCOUNT_STORE_TOKENS=True) class BitbucketOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = BitbucketOAuth2Provider.id response_data = """ { "created_on": "2011-12-20T16:34:07.132459+00:00", "display_name": "tutorials account", "links": { "avatar": { "href": "https://bitbucket-assetroot.s3.amazonaws.com/c/photos/2013/Nov/25/tutorials-avatar-1563784409-6_avatar.png" }, "followers": { "href": "https://api.bitbucket.org/2.0/users/tutorials/followers" }, "following": { "href": "https://api.bitbucket.org/2.0/users/tutorials/following" }, "html": { "href": "https://bitbucket.org/tutorials" }, "repositories": { "href": "https://api.bitbucket.org/2.0/repositories/tutorials" }, "self": { "href": "https://api.bitbucket.org/2.0/users/tutorials" } }, "location": "Santa Monica, CA", "type": "user", "username": "tutorials", "uuid": "{c788b2da-b7a2-404c-9e26-d3f077557007}", "website": "https://tutorials.bitbucket.org/" } """ # noqa email_response_data = """ { "page": 1, "pagelen": 10, "size": 1, "values": [ { "email": "tutorials@bitbucket.org", "is_confirmed": true, "is_primary": true, "links": { "self": { "href": "https://api.bitbucket.org/2.0/user/emails/tutorials@bitbucket.org" } }, "type": "email" }, { "email": "tutorials+secondary@bitbucket.org", "is_confirmed": true, "is_primary": true, "links": { "self": { "href": "https://api.bitbucket.org/2.0/user/emails/tutorials+secondary@bitbucket.org" } }, "type": "email" } ] } """ # noqa def get_mocked_response(self): return [ MockedResponse(200, self.response_data), MockedResponse(200, self.email_response_data), MockedResponse(200, self.response_data), MockedResponse(200, self.email_response_data), ] def get_expected_to_str(self): return "tutorials" def test_provider_account(self): self.login(self.get_mocked_response()) socialaccount = SocialAccount.objects.get(uid="tutorials") self.assertEqual(socialaccount.user.username, "tutorials") self.assertEqual(socialaccount.user.email, "tutorials@bitbucket.org") account = socialaccount.get_provider_account() self.assertEqual(account.to_str(), "tutorials") self.assertEqual(account.get_profile_url(), "https://bitbucket.org/tutorials") self.assertEqual( account.get_avatar_url(), "https://bitbucket-assetroot.s3.amazonaws.com/c/photos/2013/Nov/25/tutorials-avatar-1563784409-6_avatar.png", # noqa ) django-allauth-65.0.2/allauth/socialaccount/providers/bitbucket_oauth2/urls.py000066400000000000000000000002671467545753200276200ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import BitbucketOAuth2Provider urlpatterns = default_urlpatterns(BitbucketOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/bitbucket_oauth2/views.py000066400000000000000000000033561467545753200277720ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class BitbucketOAuth2Adapter(OAuth2Adapter): provider_id = "bitbucket_oauth2" access_token_url = "https://bitbucket.org/site/oauth2/access_token" authorize_url = "https://bitbucket.org/site/oauth2/authorize" profile_url = "https://api.bitbucket.org/2.0/user" emails_url = "https://api.bitbucket.org/2.0/user/emails" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json() if app_settings.QUERY_EMAIL: if email := self.get_email(token): extra_data["email"] = email return self.get_provider().sociallogin_from_response(request, extra_data) def get_email(self, token) -> str: """Fetches email address from email API endpoint""" resp = ( get_adapter() .get_requests_session() .get(self.emails_url, params={"access_token": token.token}) ) emails = resp.json().get("values", []) email = "" try: email = emails[0].get("email") primary_emails = [e for e in emails if e.get("is_primary", False)] email = primary_emails[0].get("email") except (IndexError, TypeError, KeyError): pass return email oauth_login = OAuth2LoginView.adapter_view(BitbucketOAuth2Adapter) oauth_callback = OAuth2CallbackView.adapter_view(BitbucketOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/bitly/000077500000000000000000000000001467545753200241415ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/bitly/__init__.py000066400000000000000000000000001467545753200262400ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/bitly/provider.py000066400000000000000000000014511467545753200263460ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.bitly.views import BitlyOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class BitlyAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("profile_url") def get_avatar_url(self): return self.account.extra_data.get("profile_image") class BitlyProvider(OAuth2Provider): id = "bitly" name = "Bitly" account_class = BitlyAccount oauth2_adapter_class = BitlyOAuth2Adapter def extract_uid(self, data): return str(data["login"]) def extract_common_fields(self, data): return dict(username=data["login"], name=data.get("full_name")) provider_classes = [BitlyProvider] django-allauth-65.0.2/allauth/socialaccount/providers/bitly/tests.py000066400000000000000000000020771467545753200256630ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import BitlyProvider class BitlyTests(OAuth2TestsMixin, TestCase): provider_id = BitlyProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "data": { "apiKey": "R_f6397a37e765574f2e198dba5bb59522", "custom_short_domain": null, "display_name": null, "full_name": "Bitly API Oauth Demo Account", "is_enterprise": false, "login": "bitlyapioauthdemo", "member_since": 1331567982, "profile_image": "http://bitly.com/u/bitlyapioauthdemo.png", "profile_url": "http://bitly.com/u/bitlyapioauthdemo", "share_accounts": [], "tracking_domains": [] }, "status_code": 200, "status_txt": "OK" }""", ) def get_expected_to_str(self): return "bitlyapioauthdemo" django-allauth-65.0.2/allauth/socialaccount/providers/bitly/urls.py000066400000000000000000000002441467545753200255000ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import BitlyProvider urlpatterns = default_urlpatterns(BitlyProvider) django-allauth-65.0.2/allauth/socialaccount/providers/bitly/views.py000066400000000000000000000016241467545753200256530ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class BitlyOAuth2Adapter(OAuth2Adapter): provider_id = "bitly" access_token_url = "https://api-ssl.bitly.com/oauth/access_token" authorize_url = "https://bitly.com/oauth/authorize" profile_url = "https://api-ssl.bitly.com/v3/user/info" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json()["data"] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(BitlyOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(BitlyOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/box/000077500000000000000000000000001467545753200236065ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/box/__init__.py000066400000000000000000000000001467545753200257050ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/box/provider.py000066400000000000000000000012001467545753200260030ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.box.views import BoxOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class BoxOAuth2Account(ProviderAccount): pass class BoxOAuth2Provider(OAuth2Provider): id = "box" name = "Box" account_class = BoxOAuth2Account oauth2_adapter_class = BoxOAuth2Adapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict(name=data.get("display_name"), email=data.get("email")) provider_classes = [BoxOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/box/tests.py000066400000000000000000000020711467545753200253220ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import BoxOAuth2Provider class BoxOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = BoxOAuth2Provider.id def get_mocked_response(self): return [ MockedResponse( 200, """{ "type": "user", "id": "1185237519", "name": "Balls Johnson", "login": "balls@example.com", "created_at": "2017-02-18T21:16:39-08:00", "modified_at": "2017-02-18T21:19:11-08:00", "language": "en", "timezone": "America/Los_Angeles", "space_amount": 10737418240, "space_used": 0, "max_upload_size": 2147483648, "status": "active", "job_title": "", "phone": "123-345-5555", "address": "", "avatar_url": "https://app.box.com/api/avatar/large/1185237519" }""", ) ] def get_expected_to_str(self): return "balls@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/box/urls.py000066400000000000000000000002531467545753200251450ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import BoxOAuth2Provider urlpatterns = default_urlpatterns(BoxOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/box/views.py000066400000000000000000000020411467545753200253120ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class BoxOAuth2Adapter(OAuth2Adapter): provider_id = "box" access_token_url = "https://api.box.com/oauth2/token" authorize_url = "https://account.box.com/api/oauth2/authorize" profile_url = "https://api.box.com/2.0/users/me" redirect_uri_protocol = None def complete_login(self, request, app, token, **kwargs): extra_data = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) # This only here because of weird response from the test suite if isinstance(extra_data, list): extra_data = extra_data[0] return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth_login = OAuth2LoginView.adapter_view(BoxOAuth2Adapter) oauth_callback = OAuth2CallbackView.adapter_view(BoxOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/cilogon/000077500000000000000000000000001467545753200244505ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/cilogon/__init__.py000066400000000000000000000000001467545753200265470ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/cilogon/provider.py000066400000000000000000000032361467545753200266600ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.cilogon.views import CILogonOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class Scope: OPENID = "openid" EMAIL = "email" PROFILE = "profile" USERINFO = "org.cilogon.userinfo" class CILogonAccount(ProviderAccount): pass class CILogonProvider(OAuth2Provider): id = "cilogon" name = "CILogon" account_class = CILogonAccount oauth2_adapter_class = CILogonOAuth2Adapter def get_default_scope(self): scope = [Scope.PROFILE, Scope.USERINFO, Scope.OPENID] if QUERY_EMAIL: scope.append(Scope.EMAIL) return scope def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["prompt"] = "select_account consent" return ret def extract_uid(self, data): return str(data.get("sub")) def extract_common_fields(self, data): return dict( email=data.get("email"), last_name=data.get("family_name"), first_name=data.get("given_name"), eppn=data.get("eppn"), ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("verified_email"): ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [CILogonProvider] django-allauth-65.0.2/allauth/socialaccount/providers/cilogon/tests.py000066400000000000000000000012751467545753200261710ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import CILogonProvider class CILogonTests(OAuth2TestsMixin, TestCase): provider_id = CILogonProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "email": "johndoe@example.edu", "eppn": "u1234567@example.edu", "firstname": "John", "lastname": "Doe", "idp_name": "Example University", "sub": "http://cilogon.org/serverA/users/1234567" }""", ) def get_expected_to_str(self): return "johndoe@example.edu" django-allauth-65.0.2/allauth/socialaccount/providers/cilogon/urls.py000066400000000000000000000002501467545753200260040ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import CILogonProvider urlpatterns = default_urlpatterns(CILogonProvider) django-allauth-65.0.2/allauth/socialaccount/providers/cilogon/views.py000066400000000000000000000017651467545753200261700ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class CILogonOAuth2Adapter(OAuth2Adapter): provider_id = "cilogon" access_token_url = "https://cilogon.org/oauth2/token" authorize_url = "https://cilogon.org/authorize" profile_url = "https://cilogon.org/oauth2/userinfo" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token, "alt": "json"}, ) ) resp.raise_for_status() extra_data = resp.json() login = self.get_provider().sociallogin_from_response(request, extra_data) return login oauth2_login = OAuth2LoginView.adapter_view(CILogonOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(CILogonOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/clever/000077500000000000000000000000001467545753200242765ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/clever/__init__.py000066400000000000000000000000001467545753200263750ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/clever/provider.py000066400000000000000000000033311467545753200265020ustar00rootroot00000000000000from allauth.socialaccount import providers from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.clever.views import CleverOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class CleverAccount(ProviderAccount): def get_avatar_url(self): # return self.account.extra_data.get('user').get('image_192', None) return None def get_user_data(self): return self.account.extra_data.get("data", {}) class CleverProvider(OAuth2Provider): id = "clever" name = "Clever" account_class = CleverAccount oauth2_adapter_class = CleverOAuth2Adapter def extract_uid(self, data): return data["data"]["id"] def get_user_type(self, data): return list(data.get("data", {}).get("roles", {}).keys())[0] def extract_common_fields(self, data): return dict( first_name=data.get("data", {}).get("name", {}).get("first", None), last_name=data.get("data", {}).get("name", {}).get("last", None), username=data.get("data", {}) .get("roles", {}) .get(self.get_user_type(data), {}) .get("credentials", {}) .get("district_username", None), email=data.get("data", {}).get("email", None), ) def get_default_scope(self): return [ "read:district_admins", "read:districts", "read:resources", "read:school_admins", "read:schools", "read:sections", "read:student_contacts", "read:students", "read:teachers", "read:user_id", ] providers.registry.register(CleverProvider) django-allauth-65.0.2/allauth/socialaccount/providers/clever/tests.py000066400000000000000000000026241467545753200260160ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import CleverProvider class CleverOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = CleverProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """{ "type": "user", "data": { "id": "62027798269867124d10259e", "district": "6202763c8243d2100123dae5", "type": "user", "authorized_by": "district" }, "links": [ { "rel": "self", "uri": "/me" }, { "rel": "canonical", "uri": "/v3.0/users/62027798269867124d10259e" }, { "rel": "district", "uri": "/v3.0/districts/6202763c8243d2100123dae5" } ] }""", ), MockedResponse( 200, """{ "data": { "id": "62027798269867124d10259e", "roles": { "district_admin": {}, "contact": {} } } }""", ), ] def get_expected_to_str(self): return "Clever" django-allauth-65.0.2/allauth/socialaccount/providers/clever/urls.py000066400000000000000000000002461467545753200256370ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import CleverProvider urlpatterns = default_urlpatterns(CleverProvider) django-allauth-65.0.2/allauth/socialaccount/providers/clever/views.py000066400000000000000000000031671467545753200260140ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class CleverOAuth2Adapter(OAuth2Adapter): provider_id = "clever" access_token_url = "https://clever.com/oauth/tokens" authorize_url = "https://clever.com/oauth/authorize" identity_url = "https://api.clever.com/v3.0/me" user_details_url = "https://api.clever.com/v3.0/users" def complete_login(self, request, app, token, **kwargs): extra_data = self.get_data(token.token) return self.get_provider().sociallogin_from_response(request, extra_data) def get_data(self, token): # Verify the user first resp = ( get_adapter() .get_requests_session() .get( self.identity_url, headers={"Authorization": "Bearer {}".format(token)} ) ) if resp.status_code != 200: raise OAuth2Error() resp = resp.json() user_id = resp["data"]["id"] user_details = ( get_adapter() .get_requests_session() .get( "{}/{}".format(self.user_details_url, user_id), headers={"Authorization": "Bearer {}".format(token)}, ) ) user_details.raise_for_status() user_details = user_details.json() return user_details oauth2_login = OAuth2LoginView.adapter_view(CleverOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(CleverOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/coinbase/000077500000000000000000000000001467545753200246015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/coinbase/__init__.py000066400000000000000000000000001467545753200267000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/coinbase/provider.py000066400000000000000000000015521467545753200270100ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.coinbase.views import ( CoinbaseOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class CoinbaseAccount(ProviderAccount): def get_avatar_url(self): return None class CoinbaseProvider(OAuth2Provider): id = "coinbase" name = "Coinbase" account_class = CoinbaseAccount oauth2_adapter_class = CoinbaseOAuth2Adapter def get_default_scope(self): # See: https://coinbase.com/docs/api/permissions return ["wallet:user:email"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): # See: https://coinbase.com/api/doc/1.0/users/index.html return dict(email=data["email"]) provider_classes = [CoinbaseProvider] django-allauth-65.0.2/allauth/socialaccount/providers/coinbase/tests.py000066400000000000000000000016301467545753200263150ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import CoinbaseProvider class CoinbaseTests(OAuth2TestsMixin, TestCase): provider_id = CoinbaseProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "id": "9da7a204-544e-5fd1-9a12-61176c5d4cd8", "name": "User One", "username": "user1", "email": "user1@example.com", "profile_location": null, "profile_bio": null, "profile_url": "https://coinbase.com/user1", "avatar_url": "https://images.coinbase.com/avatar?h=vR%2FY8igBoPwuwGren5JMwvDNGpURAY%2F0nRIOgH%2FY2Qh%2BQ6nomR3qusA%2Bh6o2%0Af9rH&s=128", "resource": "user", "resource_path": "/v2/user" }""", ) def get_expected_to_str(self): return "user1" django-allauth-65.0.2/allauth/socialaccount/providers/coinbase/urls.py000066400000000000000000000002521467545753200261370ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import CoinbaseProvider urlpatterns = default_urlpatterns(CoinbaseProvider) django-allauth-65.0.2/allauth/socialaccount/providers/coinbase/views.py000066400000000000000000000020101467545753200263010ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class CoinbaseOAuth2Adapter(OAuth2Adapter): provider_id = "coinbase" @property def authorize_url(self): return "https://www.coinbase.com/oauth/authorize" @property def access_token_url(self): return "https://www.coinbase.com/oauth/token" @property def profile_url(self): return "https://api.coinbase.com/v2/user" def complete_login(self, request, app, token, **kwargs): response = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token}) ) extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(CoinbaseOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(CoinbaseOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/000077500000000000000000000000001467545753200251575ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/__init__.py000066400000000000000000000000001467545753200272560ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/models.py000066400000000000000000000000001467545753200270020ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/provider.py000066400000000000000000000061401467545753200273640ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.dataporten.views import ( DataportenOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DataportenAccount(ProviderAccount): def get_avatar_url(self): """ Returns a valid URL to an 128x128 .png photo of the user """ # Documentation for user profile photos can be found here: # https://docs.dataporten.no/docs/oauth-authentication/ base_url = "https://api.dataporten.no/userinfo/v1/user/media/" return base_url + self.account.extra_data["profilephoto"] class DataportenProvider(OAuth2Provider): id = "dataporten" name = "Dataporten" account_class = DataportenAccount oauth2_adapter_class = DataportenOAuth2Adapter def extract_uid(self, data): """ Returns the primary user identifier, an UUID string See: https://docs.dataporten.no/docs/userid/ """ return data["userid"] def extract_extra_data(self, data): """ Extracts fields from `data` that will be stored in `SocialAccount`'s `extra_data` JSONField. All the necessary data extraction has already been done in the complete_login()-view, so we can just return the data. PS: This is default behaviour, so we did not really need to define this function, but it is included for documentation purposes. Typical return dict: { "userid": "76a7a061-3c55-430d-8ee0-6f82ec42501f", "userid_sec": ["feide:andreas@uninett.no"], "name": "Andreas \u00c5kre Solberg", "email": "andreas.solberg@uninett.no", "profilephoto": "p:a3019954-902f-45a3-b4ee-bca7b48ab507", } """ return data def extract_common_fields(self, data): """ This function extracts information from the /userinfo endpoint which will be consumed by allauth.socialaccount.adapter.populate_user(). Look there to find which key-value pairs that should be saved in the returned dict. Typical return dict: { "userid": "76a7a061-3c55-430d-8ee0-6f82ec42501f", "userid_sec": ["feide:andreas@uninett.no"], "name": "Andreas \u00c5kre Solberg", "email": "andreas.solberg@uninett.no", "profilephoto": "p:a3019954-902f-45a3-b4ee-bca7b48ab507", "username": "andreas", } """ # Make shallow copy to prevent possible mutability issues data = dict(data) # If a Feide username is available, use it. If not, use the "username" # of the email-address for userid in data.get("userid_sec"): usertype, username = userid.split(":") if usertype == "feide": data["username"] = username.split("@")[0] break else: # Only entered if break is not executed above data["username"] = data.get("email").split("@")[0] return data provider_classes = [DataportenProvider] django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/tests.py000066400000000000000000000053271467545753200267020ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DataportenProvider class DataportenTest(OAuth2TestsMixin, TestCase): provider_id = DataportenProvider.id def setUp(self): super(DataportenTest, self).setUp() self.mock_data = { "userid": "76a7a061-3c55-430d-8ee0-6f82ec42501f", "userid_sec": ["feide:andreas@uninett.no"], "name": "Andreas \u00c5kre Solberg", "email": "andreas.solberg@uninett.no", "profilephoto": "p:a3019954-902f-45a3-b4ee-bca7b48ab507", "groups": [{}], } def get_login_response_json(self, with_refresh_token=True): rt = "" if with_refresh_token: rt = ',"refresh_token": "testrf"' return ( """{ "access_token":"testac", "expires_in":3600, "scope": "userid profile groups" %s }""" % rt ) def get_mocked_response(self): return MockedResponse( status_code=200, content="""{ "user": { "userid": "76a7a061-3c55-430d-8ee0-6f82ec42501f", "userid_sec": ["feide:andreas@uninett.no"], "name": "Andreas \u00c5kre Solberg", "email": "andreas.solberg@uninett.no", "profilephoto": "p:a3019954-902f-45a3-b4ee-bca7b48ab507" }, "audience": "app123id" }""", headers={"content-type": "application/json"}, ) def get_expected_to_str(self): return "andreas.solberg@uninett.no" def test_extract_uid(self): uid = self.provider.extract_uid(self.mock_data) self.assertEqual(uid, self.mock_data["userid"]) def test_extract_extra_data(self): # All the processing is done in the complete_login view, and thus # the data should be returned unaltered extra_data = self.provider.extract_extra_data(self.mock_data) self.assertEqual(extra_data, self.mock_data) def test_extract_common_fields(self): # The main task of this function is to parse the data in order to # find the Feide username, and if not, use the email common_fields = self.provider.extract_common_fields(self.mock_data) self.assertEqual(common_fields["username"], "andreas") # Test correct behaviour when Feide username is unavailable new_mock_data = dict(self.mock_data) new_mock_data["userid_sec"] = [] new_common_fields = self.provider.extract_common_fields(new_mock_data) self.assertEqual(new_common_fields["username"], "andreas.solberg") django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/urls.py000066400000000000000000000002561467545753200265210ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DataportenProvider urlpatterns = default_urlpatterns(DataportenProvider) django-allauth-65.0.2/allauth/socialaccount/providers/dataporten/views.py000066400000000000000000000050071467545753200266700ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.base import ProviderException from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DataportenOAuth2Adapter(OAuth2Adapter): provider_id = "dataporten" access_token_url = "https://auth.dataporten.no/oauth/token" authorize_url = "https://auth.dataporten.no/oauth/authorization" profile_url = "https://auth.dataporten.no/userinfo" groups_url = "https://groups-api.dataporten.no/groups/" def complete_login(self, request, app, token, **kwargs): """ Arguments: request - The get request to the callback URL /accounts/dataporten/login/callback. app - The corresponding SocialApp model instance token - A token object with access token given in token.token Returns: Should return a dict with user information intended for parsing by the methods of the DataportenProvider view, i.e. extract_uid(), extract_extra_data(), and extract_common_fields() """ # The authentication header headers = {"Authorization": "Bearer " + token.token} # Userinfo endpoint, for documentation see: # https://docs.dataporten.no/docs/oauth-authentication/ userinfo_response = ( get_adapter() .get_requests_session() .get( self.profile_url, headers=headers, ) ) # Raise exception for 4xx and 5xx response codes userinfo_response.raise_for_status() # The endpoint returns json-data and it needs to be decoded extra_data = userinfo_response.json()["user"] # Finally test that the audience property matches the client id # for validification reasons, as instructed by the Dataporten docs # if the userinfo-response is used for authentication if userinfo_response.json()["audience"] != app.client_id: raise ProviderException( "Dataporten returned a user with an audience field \ which does not correspond to the client id of the \ application." ) return self.get_provider().sociallogin_from_response( request, extra_data, ) oauth2_login = OAuth2LoginView.adapter_view(DataportenOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DataportenOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/daum/000077500000000000000000000000001467545753200237445ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/daum/__init__.py000066400000000000000000000000001467545753200260430ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/daum/models.py000066400000000000000000000000001467545753200255670ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/daum/provider.py000066400000000000000000000011221467545753200261440ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.daum.views import DaumOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DaumAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("bigImagePath") class DaumProvider(OAuth2Provider): id = "Daum" name = "Daum" account_class = DaumAccount oauth2_adapter_class = DaumOAuth2Adapter def extract_uid(self, data): return str(data.get("id")) provider_classes = [DaumProvider] django-allauth-65.0.2/allauth/socialaccount/providers/daum/tests.py000066400000000000000000000013571467545753200254660ustar00rootroot00000000000000import json from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DaumProvider class DaumTests(OAuth2TestsMixin, TestCase): provider_id = DaumProvider.id def get_mocked_response(self): result = {} result["userid"] = "38DTh" result["id"] = 46287445 result["nickname"] = "xncbf" result["bigImagePath"] = "https://img1.daumcdn.net/thumb/" result["openProfile"] = "https://img1.daumcdn.net/thumb/" body = {} body["code"] = 200 body["message"] = "OK" body["result"] = result return MockedResponse(200, json.dumps(body)) def get_expected_to_str(self): return "xncbf" django-allauth-65.0.2/allauth/socialaccount/providers/daum/urls.py000066400000000000000000000002421467545753200253010ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DaumProvider urlpatterns = default_urlpatterns(DaumProvider) django-allauth-65.0.2/allauth/socialaccount/providers/daum/views.py000066400000000000000000000016221467545753200254540ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DaumOAuth2Adapter(OAuth2Adapter): provider_id = "Daum" access_token_url = "https://apis.daum.net/oauth2/token" authorize_url = "https://apis.daum.net/oauth2/authorize" profile_url = "https://apis.daum.net/user/v1/show.json" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json().get("result") return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DaumOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DaumOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/digitalocean/000077500000000000000000000000001467545753200254415ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/digitalocean/__init__.py000066400000000000000000000000001467545753200275400ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/digitalocean/provider.py000066400000000000000000000014121467545753200276430ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.digitalocean.views import ( DigitalOceanOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DigitalOceanAccount(ProviderAccount): def get_user_data(self): return self.account.extra_data.get("account", {}) class DigitalOceanProvider(OAuth2Provider): id = "digitalocean" name = "DigitalOcean" account_class = DigitalOceanAccount oauth2_adapter_class = DigitalOceanOAuth2Adapter def extract_uid(self, data): return str(data["account"]["uuid"]) def extract_common_fields(self, data): return dict(email=data["account"]["email"]) provider_classes = [DigitalOceanProvider] django-allauth-65.0.2/allauth/socialaccount/providers/digitalocean/tests.py000066400000000000000000000023241467545753200271560ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DigitalOceanProvider class DigitalOceanTests(OAuth2TestsMixin, TestCase): provider_id = DigitalOceanProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "account": { "droplet_limit": 25, "floating_ip_limit": 5, "email": "sammy@example.com", "uuid": "b6fr89dbf6d9156cace5f3c78dc9851d957381ef", "email_verified": true, "status": "active", "status_message": "" } } """, ) def get_login_response_json(self, with_refresh_token=True): return """ { "access_token": "testac", "token_type": "bearer", "expires_in": 2592000, "refresh_token": "00a3aae641658d", "scope": "read write", "info": { "name": "Sammy the Shark", "email":"sammy@example.com", "uuid":"b6fr89dbf6d9156cace5f3c78dc9851d957381ef" } }""" def get_expected_to_str(self): return "sammy@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/digitalocean/urls.py000066400000000000000000000002621467545753200270000ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DigitalOceanProvider urlpatterns = default_urlpatterns(DigitalOceanProvider) django-allauth-65.0.2/allauth/socialaccount/providers/digitalocean/views.py000066400000000000000000000017211467545753200271510ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DigitalOceanOAuth2Adapter(OAuth2Adapter): provider_id = "digitalocean" access_token_url = "https://cloud.digitalocean.com/v1/oauth/token" authorize_url = "https://cloud.digitalocean.com/v1/oauth/authorize" profile_url = "https://api.digitalocean.com/v2/account" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DigitalOceanOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DigitalOceanOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/000077500000000000000000000000001467545753200246135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/__init__.py000066400000000000000000000000001467545753200267120ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/client.py000066400000000000000000000025051467545753200264450ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) class DingTalkOAuth2Client(OAuth2Client): def get_access_token(self, code, pkce_code_verifier=None): data = { "clientId": self.consumer_key, "clientSecret": self.consumer_secret, "code": code, "grantType": "authorization_code", } params = None if pkce_code_verifier: data["code_verifier"] = pkce_code_verifier self._strip_empty_keys(data) url = self.access_token_url if self.access_token_method == "GET": params = data data = None resp = ( get_adapter() .get_requests_session() .request(self.access_token_method, url, params=params, json=data) ) resp.raise_for_status() access_token = resp.json() if not access_token or "accessToken" not in access_token: raise OAuth2Error("Error retrieving access token: %s" % resp.content) access_token["access_token"] = access_token.pop("accessToken") access_token["refresh_token"] = access_token.pop("refreshToken") access_token["expires_in"] = access_token.pop("expireIn") return access_token django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/provider.py000066400000000000000000000016661467545753200270300ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.dingtalk.views import ( DingTalkOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DingTalkAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("avatarUrl") def to_str(self): return self.account.extra_data.get( "nick", super(DingTalkAccount, self).to_str() ) class DingTalkProvider(OAuth2Provider): id = "dingtalk" name = "DingTalk" account_class = DingTalkAccount oauth2_adapter_class = DingTalkOAuth2Adapter def extract_uid(self, data): return data["openId"] def get_default_scope(self): return ["openid", "corpid"] def extract_common_fields(self, data): return dict(username=data.get("nick"), name=data.get("nick")) provider_classes = [DingTalkProvider] django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/tests.py000066400000000000000000000015061467545753200263310ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DingTalkProvider class DingTalkTests(OAuth2TestsMixin, TestCase): provider_id = DingTalkProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "nick": "aiden", "unionId": "hTaCSb1nM4RXii6jaQvHZqQiEiE", "avatarUrl": "https://static-legacy.dingtalk.com/media/lADPDg7mViaksW3NBJPNBJI_1170_1171.jpg", "openId": "ELdCPlk0V2LodZHx3n0p5AiEiE" }""", ) def get_login_response_json(self, with_refresh_token=True): return """{ "accessToken": "testac", "expireIn": "3600", "refreshToken": "testrf" }""" def get_expected_to_str(self): return "aiden" django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/urls.py000066400000000000000000000002521467545753200261510ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DingTalkProvider urlpatterns = default_urlpatterns(DingTalkProvider) django-allauth-65.0.2/allauth/socialaccount/providers/dingtalk/views.py000066400000000000000000000026041467545753200263240ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .client import DingTalkOAuth2Client class DingTalkOAuth2Adapter(OAuth2Adapter): provider_id = "dingtalk" access_token_url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken" authorize_url = "https://login.dingtalk.com/oauth2/auth" profile_url = "https://api.dingtalk.com/v1.0/contact/users/me" client_class = DingTalkOAuth2Client def __init__(self, request): # dingtalk set "authCode" instead of "code" in callback url if "authCode" in request.GET: request.GET._mutable = True request.GET["code"] = request.GET["authCode"] request.GET._mutable = False super(DingTalkOAuth2Adapter, self).__init__(request) def complete_login(self, request, app, token, **kwargs): headers = {"x-acs-dingtalk-access-token": token.token} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DingTalkOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DingTalkOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/discord/000077500000000000000000000000001467545753200244455ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/discord/__init__.py000066400000000000000000000000001467545753200265440ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/discord/provider.py000066400000000000000000000067041467545753200266600ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.discord.views import DiscordOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DiscordAccount(ProviderAccount): def validate_descriminator(self, discriminator): if not isinstance(discriminator, str): return False # As of 2023-06-22, Discord returns string literal '0' for users # with no discriminator return len(discriminator) == 4 if discriminator.isdigit() else False def is_new_username_system(self): if not isinstance(self.account.extra_data, dict): return None discriminator = self.account.extra_data.get("discriminator") if self.validate_descriminator(discriminator): return False if self.account.extra_data.get("global_name") is not None: return True return None def to_str(self): fallback = super(DiscordAccount, self).to_str() # If the extra_data is malformed, exit early if not isinstance(self.account.extra_data, dict): return fallback is_new_system = self.is_new_username_system() if is_new_system is None: # We couldn't determine if the username is new or old # so we'll just return the username on it's own. display_name = self.account.extra_data.get("username") elif is_new_system: # global_name can be None or even undefined # so we'll use the username as a fallback global_name = self.account.extra_data.get("global_name") username = self.account.extra_data.get("username") display_name = global_name or username else: # Looks like it's the old username system # so we'll just use the username and discriminator display_name = "{username}#{discriminator}".format( username=self.account.extra_data.get("username"), discriminator=self.account.extra_data.get("discriminator"), ) # It's very unlikely but still possible that the display_name is None # so we'll return or'd against the fallback just incase. We don't want # to return None as users of the library expect this to be str. return display_name or fallback def get_avatar_url(self): if ( "id" in self.account.extra_data.keys() and "avatar" in self.account.extra_data.keys() ): return "https://cdn.discordapp.com/avatars/{id}/{avatar}.png".format( **self.account.extra_data ) class DiscordProvider(OAuth2Provider): id = "discord" name = "Discord" account_class = DiscordAccount oauth2_adapter_class = DiscordOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), name=data.get("username"), ) def get_default_scope(self): return ["email", "identify"] def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("verified"): ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [DiscordProvider] django-allauth-65.0.2/allauth/socialaccount/providers/discord/tests.py000066400000000000000000000066261467545753200261730ustar00rootroot00000000000000from django.contrib.auth import get_user_model from allauth.account.models import EmailAddress from allauth.account.utils import user_email, user_username from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.discord.provider import DiscordProvider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class DiscordTests(OAuth2TestsMixin, TestCase): provider_id = DiscordProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "id": "80351110224678912", "username": "nelly", "discriminator": "0", "global_name": "Nelly", "avatar": "8342729096ea3675442027381ff50dfe", "verified": true, "email": "nelly@example.com" }""", ) def get_expected_to_str(self): return "Nelly" def test_display_name(self, multiple_login=False): email = "user@example.com" user = get_user_model()(is_active=True) user_email(user, email) user_username(user, "user") user.set_password("test") user.save() EmailAddress.objects.create(user=user, email=email, primary=True, verified=True) self.client.login(username=user.username, password="test") self.login(self.get_mocked_response(), process="connect") if multiple_login: self.login( self.get_mocked_response(), with_refresh_token=False, process="connect", ) # get account sa = SocialAccount.objects.filter(user=user, provider=self.provider.id).get() # The following lines don't actually test that much, but at least # we make sure that the code is hit. provider_account = sa.get_provider_account() self.assertEqual(provider_account.to_str(), "Nelly") class OldDiscordTests(DiscordTests, TestCase): provider_id = DiscordProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "id": "80351110224678912", "username": "Nelly", "discriminator": "1337", "avatar": "8342729096ea3675442027381ff50dfe", "verified": true, "email": "nelly@example.com" }""", ) def get_expected_to_str(self): return "Nelly#1337" def test_display_name(self, multiple_login=False): email = "user@example.com" user = get_user_model()(is_active=True) user_email(user, email) user_username(user, "user") user.set_password("test") user.save() EmailAddress.objects.create(user=user, email=email, primary=True, verified=True) self.client.login(username=user.username, password="test") self.login(self.get_mocked_response(), process="connect") if multiple_login: self.login( self.get_mocked_response(), with_refresh_token=False, process="connect", ) # get account sa = SocialAccount.objects.filter(user=user, provider=self.provider.id).get() # The following lines don't actually test that much, but at least # we make sure that the code is hit. provider_account = sa.get_provider_account() self.assertEqual(provider_account.to_str(), "Nelly#1337") django-allauth-65.0.2/allauth/socialaccount/providers/discord/urls.py000066400000000000000000000003161467545753200260040ustar00rootroot00000000000000from allauth.socialaccount.providers.discord.provider import DiscordProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(DiscordProvider) django-allauth-65.0.2/allauth/socialaccount/providers/discord/views.py000066400000000000000000000017311467545753200261560ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DiscordOAuth2Adapter(OAuth2Adapter): provider_id = "discord" access_token_url = "https://discord.com/api/oauth2/token" authorize_url = "https://discord.com/api/oauth2/authorize" profile_url = "https://discord.com/api/users/@me" def complete_login(self, request, app, token, **kwargs): headers = { "Authorization": "Bearer {0}".format(token.token), "Content-Type": "application/json", } extra_data = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth2_login = OAuth2LoginView.adapter_view(DiscordOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DiscordOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/disqus/000077500000000000000000000000001467545753200243265ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/disqus/__init__.py000066400000000000000000000000001467545753200264250ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/disqus/provider.py000066400000000000000000000025221467545753200265330ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.disqus.views import DisqusOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DisqusAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("profileUrl") def get_avatar_url(self): return self.account.extra_data.get("avatar", {}).get("permalink") class DisqusProvider(OAuth2Provider): id = "disqus" name = "Disqus" account_class = DisqusAccount oauth2_adapter_class = DisqusOAuth2Adapter def get_default_scope(self): scope = ["read"] if QUERY_EMAIL: scope += ["email"] return scope def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return { "username": data.get("username"), "email": data.get("email"), "name": data.get("name"), } def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [DisqusProvider] django-allauth-65.0.2/allauth/socialaccount/providers/disqus/tests.py000066400000000000000000000041031467545753200260400ustar00rootroot00000000000000from django.contrib.auth.models import User from django.test.utils import override_settings from allauth.account import app_settings as account_settings from allauth.account.models import EmailAddress from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DisqusProvider @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=True, ACCOUNT_SIGNUP_FORM_CLASS=None, ACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.MANDATORY, ) class DisqusTests(OAuth2TestsMixin, TestCase): provider_id = DisqusProvider.id def get_mocked_response( self, name="Raymond Penners", email="raymond.penners@example.com" ): return MockedResponse( 200, """ {"response": {"name": "%s", "avatar": { "permalink": "https://lh5.googleusercontent.com/photo.jpg" }, "email": "%s", "profileUrl": "https://plus.google.com/108204268033311374519", "id": "108204268033311374519" }} """ % (name, email), ) def get_expected_to_str(self): return "raymond.penners@example.com" def test_account_connect(self): email = "user@example.com" user = User.objects.create(username="user", is_active=True, email=email) user.set_password("test") user.save() EmailAddress.objects.create(user=user, email=email, primary=True, verified=True) self.client.login(username=user.username, password="test") self.login(self.get_mocked_response(), process="connect") # Check if we connected... self.assertTrue( SocialAccount.objects.filter(user=user, provider=DisqusProvider.id).exists() ) # For now, we do not pick up any new email addresses on connect self.assertEqual(EmailAddress.objects.filter(user=user).count(), 1) self.assertEqual(EmailAddress.objects.filter(user=user, email=email).count(), 1) django-allauth-65.0.2/allauth/socialaccount/providers/disqus/urls.py000066400000000000000000000002461467545753200256670ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DisqusProvider urlpatterns = default_urlpatterns(DisqusProvider) django-allauth-65.0.2/allauth/socialaccount/providers/disqus/views.py000066400000000000000000000022671467545753200260440ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DisqusOAuth2Adapter(OAuth2Adapter): provider_id = "disqus" access_token_url = "https://disqus.com/api/oauth/2.0/access_token/" authorize_url = "https://disqus.com/api/oauth/2.0/authorize/" profile_url = "https://disqus.com/api/3.0/users/details.json" scope_delimiter = "," def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={ "access_token": token.token, "api_key": app.client_id, "api_secret": app.secret, }, ) ) resp.raise_for_status() extra_data = resp.json().get("response") login = self.get_provider().sociallogin_from_response(request, extra_data) return login oauth2_login = OAuth2LoginView.adapter_view(DisqusOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DisqusOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/douban/000077500000000000000000000000001467545753200242665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/douban/__init__.py000077500000000000000000000000001467545753200263700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/douban/provider.py000077500000000000000000000024241467545753200264770ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.douban.views import DoubanOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DoubanAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("alt") def get_avatar_url(self): return self.account.extra_data.get("large_avatar") class DoubanProvider(OAuth2Provider): id = "douban" name = "Douban" account_class = DoubanAccount oauth2_adapter_class = DoubanOAuth2Adapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): """ Extract data from profile json to populate user instance. In Douban profile API: - id: a digital string, will never change - uid: defaults to id, but can be changed once, used in profile url, like slug - name: display name, can be changed every 30 days So we should use `id` as username here, other than `uid`. Also use `name` as `first_name` for displaying purpose. """ return { "username": data["id"], "first_name": data.get("name", ""), } provider_classes = [DoubanProvider] django-allauth-65.0.2/allauth/socialaccount/providers/douban/tests.py000077500000000000000000000016461467545753200260140ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DoubanProvider class DoubanTests(OAuth2TestsMixin, TestCase): provider_id = DoubanProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"name": "guoqiao", "created": "2009-02-18 01:07:52", "is_suicide": false, "alt": "http://www.douban.com/people/qguo/", "avatar": "http://img3.douban.com/icon/u3659811-3.jpg", "signature": "", "uid": "qguo", "is_banned": false, "desc": "\u4e0d\u662f\u5f88\u7231\u8bfb\u4e66", "type": "user", "id": "3659811", "large_avatar": "http://img3.douban.com/icon/up3659811-3.jpg"} """, ) def get_expected_to_str(self): return "guoqiao" django-allauth-65.0.2/allauth/socialaccount/providers/douban/urls.py000077500000000000000000000002461467545753200256320ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DoubanProvider urlpatterns = default_urlpatterns(DoubanProvider) django-allauth-65.0.2/allauth/socialaccount/providers/douban/views.py000077500000000000000000000025541467545753200260060ustar00rootroot00000000000000from django.utils.translation import gettext_lazy as _ from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from ..base import ProviderException class DoubanOAuth2Adapter(OAuth2Adapter): provider_id = "douban" access_token_url = "https://www.douban.com/service/auth2/token" authorize_url = "https://www.douban.com/service/auth2/auth" profile_url = "https://api.douban.com/v2/user/~me" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer %s" % token.token} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() """ Douban may return data like this: { 'code': 128, 'request': 'GET /v2/user/~me', 'msg': 'user_is_locked:53358092' } """ if "id" not in extra_data: msg = extra_data.get("msg", _("Invalid profile data")) raise ProviderException(msg) return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DoubanOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DoubanOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/doximity/000077500000000000000000000000001467545753200246645ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/doximity/__init__.py000066400000000000000000000000001467545753200267630ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/doximity/provider.py000066400000000000000000000020511467545753200270660ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.doximity.views import ( DoximityOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DoximityAccount(ProviderAccount): def get_profile_url(self): return None def get_avatar_url(self): return self.account.extra_data.get("profile_photo") class DoximityProvider(OAuth2Provider): id = "doximity" name = "Doximity" account_class = DoximityAccount oauth2_adapter_class = DoximityOAuth2Adapter def extract_uid(self, data): return str(data["id"]) # the Doximity id is long def extract_common_fields(self, data): return dict( username=data.get("email"), first_name=data.get("firstname"), last_name=data.get("lastname"), email=data.get("email"), name=data.get("full_name"), ) def get_default_scope(self): return ["basic", "email"] provider_classes = [DoximityProvider] django-allauth-65.0.2/allauth/socialaccount/providers/doximity/tests.py000066400000000000000000000042771467545753200264120ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DoximityProvider class DoximityTests(OAuth2TestsMixin, TestCase): provider_id = DoximityProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "id": 41993552342, "npi": 1952635229, "firstname": "John", "middlename": "Henry", "maiden_name": null, "lastname": "Smith", "full_name": "Ahmed S Belal, MD", "gender": "M", "city": "San Francisco", "state": "CA", "zip": "94107", "phone": "(650) 200-3901", "fax": "888-416-8572", "email": "abelalmd@example.com", "address_1": "500 3rd St.", "address_2": "Suite 510", "lat": 42.3663926, "lon": -71.051395, "additional_locations": [{ "address_1": "12 Main st", "address_2": null, "city": "Cambridge", "state": "MA", "phone": "555-555-5555", "fax": null, "zip": "02138" }], "credentials": "MD", "verified": true, "description": "Chief of Cardiology", "medical_school": "UCSF School of Medicine", "residencies": ["Stanford Medical Center", "Mt Sinai Hospital"], "specialty": "Cardiology", "specialty_details": { "abbr": "Cards", "code": "CA00", "credential_id": 4, "name": "Cardiology", "id": "CA00" }, "hospitals": [{ "name": "Mills-Peninsula Health Services", "aha_id": "6930315" }], "subspecialties": ["General Cardiology", "Cardiac Disease"], "profile_photo": "https://s3.amazonaws.com/doximity_prod_uploads\ /profile_photos/7969/normal/profile.png", "colleague_count": 142 } """, ) def get_expected_to_str(self): return "abelalmd@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/doximity/urls.py000066400000000000000000000002521467545753200262220ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DoximityProvider urlpatterns = default_urlpatterns(DoximityProvider) django-allauth-65.0.2/allauth/socialaccount/providers/doximity/views.py000066400000000000000000000016601467545753200263760ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DoximityOAuth2Adapter(OAuth2Adapter): provider_id = "doximity" access_token_url = "https://auth.doximity.com/oauth/token" authorize_url = "https://auth.doximity.com/oauth/authorize" profile_url = "https://www.doximity.com/api/v1/users/current" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer %s" % token.token} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DoximityOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DoximityOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/draugiem/000077500000000000000000000000001467545753200246135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/draugiem/__init__.py000066400000000000000000000000001467545753200267120ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/draugiem/provider.py000066400000000000000000000027471467545753200270310ustar00rootroot00000000000000from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.providers.base import Provider, ProviderAccount class DraugiemAccount(ProviderAccount): def get_avatar_url(self): ret = None pic_small_url = self.account.extra_data.get("img") pic_icon_url = self.account.extra_data.get("imgi") pic_medium_url = self.account.extra_data.get("imgm") pic_large_url = self.account.extra_data.get("imgl") if pic_large_url: return pic_large_url elif pic_medium_url: return pic_medium_url elif pic_icon_url: return pic_icon_url elif pic_small_url: return pic_small_url else: return ret class DraugiemProvider(Provider): id = "draugiem" name = "Draugiem" account_class = DraugiemAccount def get_login_url(self, request, **kwargs): url = reverse(self.id + "_login") if kwargs: url = url + "?" + urlencode(kwargs) return url def extract_uid(self, data): return str(data["uid"]) def extract_common_fields(self, data): uid = self.extract_uid(data) user_data = data["users"][uid] return dict( first_name=user_data.get("name"), last_name=user_data.get("surname"), ) def extract_extra_data(self, data): uid = self.extract_uid(data) return data["users"][uid] provider_classes = [DraugiemProvider] django-allauth-65.0.2/allauth/socialaccount/providers/draugiem/tests.py000066400000000000000000000124261467545753200263340ustar00rootroot00000000000000import time from hashlib import md5 from unittest.mock import Mock, patch from django.contrib.auth.models import User from django.test import RequestFactory from django.urls import reverse from django.utils.http import urlencode from allauth import app_settings from allauth.socialaccount.internal import statekit from allauth.socialaccount.models import SocialAccount, SocialApp, SocialToken from allauth.tests import TestCase from . import views from .provider import DraugiemProvider class DraugiemTests(TestCase): def setUp(self): # workaround to create a session. see: # https://code.djangoproject.com/ticket/11475 User.objects.create_user( "anakin", "skywalker@deathstar.example.com", "s1thrul3s" ) self.client.login(username="anakin", password="s1thrul3s") app = SocialApp.objects.create( provider=DraugiemProvider.id, name=DraugiemProvider.id, client_id="app123id", key=DraugiemProvider.id, secret="dummy", ) request = RequestFactory().get("/") self.provider = app.get_provider(request) if app_settings.SITES_ENABLED: from django.contrib.sites.models import Site app.sites.add(Site.objects.get_current()) self.app = app def get_draugiem_login_response(self): """ Sample Draugiem.lv response """ return { "apikey": "12345", "uid": "42", "users": { "42": { "age": "266", "imgl": "http://cdn.memegenerator.net/instances/500x/23395689.jpg", "surname": "Skywalker", "url": "/user/42/", "imgi": "http://cdn.memegenerator.net/instances/500x/23395689.jpg", "nick": "Sky Guy", "created": "09.11.1812 11:26:15", "deleted": "false", "imgm": "http://cdn.memegenerator.net/instances/500x/23395689.jpg", "sex": "M", "type": "User_Default", "uid": "42", "place": "London", "emailHash": "3f198f21434gfd2f2b4rs05939shk93f3815bc6aa", "name": "Anakin", "adult": "1", "birthday": "1750-09-13", "img": "http://cdn.memegenerator.net/instances/500x/23395689.jpg", } }, } def get_socialaccount(self, response, token): """ Returns SocialLogin based on the data from the request """ request = Mock() login = self.provider.sociallogin_from_response(request, response) login.token = token return login def mock_socialaccount_state(self): """ SocialLogin depends on Session state - a tuple of request params and a random string """ session = self.client.session session[statekit.STATES_SESSION_KEY] = { "12345": ({"process": "login", "scope": "", "auth_params": ""}, time.time()) } session.save() def test_login_redirect(self): response = self.client.get(reverse(views.login)) redirect_url = reverse(views.callback) full_redirect_url = "http://testserver" + redirect_url secret = self.app.secret + full_redirect_url redirect_url_hash = md5(secret.encode("utf-8")).hexdigest() params = { "app": self.app.client_id, "hash": redirect_url_hash, "redirect": full_redirect_url, } self.assertRedirects( response, "%s?%s" % (views.AUTHORIZE_URL, urlencode(params)), fetch_redirect_response=False, ) def test_callback_no_auth_status(self): response = self.client.get(reverse(views.callback)) self.assertTemplateUsed(response, "socialaccount/authentication_error.html") def test_callback_invalid_auth_status(self): response = self.client.get(reverse(views.callback), {"dr_auth_status": "fail"}) self.assertTemplateUsed(response, "socialaccount/authentication_error.html") def test_callback(self): with patch( "allauth.socialaccount.providers.draugiem.views.draugiem_complete_login" ) as draugiem_complete_login: self.mock_socialaccount_state() response_json = self.get_draugiem_login_response() token = SocialToken(app=self.app, token=response_json["apikey"]) login = self.get_socialaccount(response_json, token) draugiem_complete_login.return_value = login response = self.client.get( reverse(views.callback), {"dr_auth_status": "ok", "dr_auth_code": "42"}, ) self.assertRedirects( response, "/accounts/profile/", fetch_redirect_response=False ) socialaccount = SocialAccount.objects.filter( provider=DraugiemProvider.id ).last() pacc = socialaccount.get_provider_account() assert ( pacc.get_avatar_url() == "http://cdn.memegenerator.net/instances/500x/23395689.jpg" ) assert pacc.to_str() == "Anakin" django-allauth-65.0.2/allauth/socialaccount/providers/draugiem/urls.py000066400000000000000000000003211467545753200261460ustar00rootroot00000000000000from django.urls import path from . import views urlpatterns = [ path("draugiem/login/", views.login, name="draugiem_login"), path("draugiem/callback/", views.callback, name="draugiem_callback"), ] django-allauth-65.0.2/allauth/socialaccount/providers/draugiem/views.py000066400000000000000000000053471467545753200263330ustar00rootroot00000000000000import requests from hashlib import md5 from django.http import HttpResponseRedirect from django.urls import reverse from django.utils.http import urlencode from django.views.decorators.csrf import csrf_exempt from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.models import SocialLogin, SocialToken from ..base import AuthError from .provider import DraugiemProvider class DraugiemApiError(Exception): pass ACCESS_TOKEN_URL = "http://api.draugiem.lv/json" AUTHORIZE_URL = "http://api.draugiem.lv/authorize" def login(request): app = get_adapter().get_app(request, DraugiemProvider.id) redirect_url = request.build_absolute_uri(reverse(callback)) redirect_url_hash = md5((app.secret + redirect_url).encode("utf-8")).hexdigest() params = { "app": app.client_id, "hash": redirect_url_hash, "redirect": redirect_url, } SocialLogin.stash_state(request) return HttpResponseRedirect("%s?%s" % (AUTHORIZE_URL, urlencode(params))) @csrf_exempt def callback(request): adapter = get_adapter() provider = adapter.get_provider(request, DraugiemProvider.id) if "dr_auth_status" not in request.GET: return render_authentication_error(request, provider, error=AuthError.UNKNOWN) if request.GET["dr_auth_status"] != "ok": return render_authentication_error(request, provider, error=AuthError.DENIED) if "dr_auth_code" not in request.GET: return render_authentication_error(request, provider, error=AuthError.UNKNOWN) ret = None auth_exception = None try: app = provider.app login = draugiem_complete_login(request, app, request.GET["dr_auth_code"]) login.state = SocialLogin.unstash_state(request) ret = complete_social_login(request, login) except (requests.RequestException, DraugiemApiError) as e: auth_exception = e if not ret: ret = render_authentication_error(request, provider, exception=auth_exception) return ret def draugiem_complete_login(request, app, code): provider = get_adapter().get_provider(request, DraugiemProvider.id) response = ( get_adapter() .get_requests_session() .get( ACCESS_TOKEN_URL, {"action": "authorize", "app": app.secret, "code": code}, ) ) response.raise_for_status() response_json = response.json() if "error" in response_json: raise DraugiemApiError(response_json["error"]) token = SocialToken(app=app, token=response_json["apikey"]) login = provider.sociallogin_from_response(request, response_json) login.token = token return login django-allauth-65.0.2/allauth/socialaccount/providers/drip/000077500000000000000000000000001467545753200237545ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/drip/__init__.py000066400000000000000000000000001467545753200260530ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/drip/provider.py000066400000000000000000000017231467545753200261630ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.drip.views import DripOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DripAccount(ProviderAccount): pass class DripProvider(OAuth2Provider): id = "drip" name = "Drip" account_class = DripAccount oauth2_adapter_class = DripOAuth2Adapter def extract_uid(self, data): # no uid available, we generate one by hashing the email uid = hash(data.get("email")) return str(uid) def extract_common_fields(self, data): return dict(email=data.get("email"), name=data.get("name")) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [DripProvider] django-allauth-65.0.2/allauth/socialaccount/providers/drip/tests.py000066400000000000000000000011101467545753200254610ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DripProvider class DripTests(OAuth2TestsMixin, TestCase): provider_id = DripProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "users":[{ "email": "john@acme.com", "name": "John Doe", "time_zone": "America/Los_Angeles" }] }""", ) def get_expected_to_str(self): return "john@acme.com" django-allauth-65.0.2/allauth/socialaccount/providers/drip/urls.py000066400000000000000000000002421467545753200253110ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DripProvider urlpatterns = default_urlpatterns(DripProvider) django-allauth-65.0.2/allauth/socialaccount/providers/drip/views.py000066400000000000000000000021201467545753200254560ustar00rootroot00000000000000"""Views for Drip API.""" from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DripOAuth2Adapter(OAuth2Adapter): """OAuth2Adapter for Drip API v3.""" provider_id = "drip" authorize_url = "https://www.getdrip.com/oauth/authorize" access_token_url = "https://www.getdrip.com/oauth/token" profile_url = "https://api.getdrip.com/v2/user" def complete_login(self, request, app, token, **kwargs): """Complete login, ensuring correct OAuth header.""" headers = {"Authorization": "Bearer {0}".format(token.token)} response = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) response.raise_for_status() extra_data = response.json()["users"][0] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DripOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DripOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/dropbox/000077500000000000000000000000001467545753200244735ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dropbox/__init__.py000066400000000000000000000000001467545753200265720ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dropbox/provider.py000066400000000000000000000013401467545753200266750ustar00rootroot00000000000000from allauth.socialaccount import providers from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.dropbox.views import DropboxOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DropboxOAuth2Account(ProviderAccount): pass class DropboxOAuth2Provider(OAuth2Provider): id = "dropbox" name = "Dropbox" account_class = DropboxOAuth2Account oauth2_adapter_class = DropboxOAuth2Adapter def extract_uid(self, data): return data["account_id"] def extract_common_fields(self, data): return dict(name=data["name"]["display_name"], email=data["email"]) providers.registry.register(DropboxOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/dropbox/tests.py000066400000000000000000000023671467545753200262170ustar00rootroot00000000000000import json from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DropboxOAuth2Provider class DropboxOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = DropboxOAuth2Provider.id def get_mocked_response(self): payload = { "account_id": "dbid:ASDFasd3ASdfasdFAsd1AS2ASDF1aS-DfAs", "account_type": {".tag": "basic"}, "country": "US", "disabled": False, "email": "allauth@example.com", "email_verified": True, "is_paired": True, "locale": "en", "name": { "abbreviated_name": "AA", "display_name": "All Auth", "familiar_name": "All", "given_name": "All", "surname": "Auth", }, "profile_photo_url": ( "https://dl-web.dropbox.com/account_photo" "/get/dbid%ASDFasd3ASdfasdFAsd1AS2ASDF1aS" "-DfAs?size=128x128" ), "referral_link": "https://db.tt/ASDfAsDf", } return MockedResponse(200, json.dumps(payload)) def get_expected_to_str(self): return "allauth@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/dropbox/urls.py000066400000000000000000000002631467545753200260330ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import DropboxOAuth2Provider urlpatterns = default_urlpatterns(DropboxOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/dropbox/views.py000066400000000000000000000017551467545753200262120ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class DropboxOAuth2Adapter(OAuth2Adapter): provider_id = "dropbox" access_token_url = "https://api.dropbox.com/oauth2/token" authorize_url = "https://www.dropbox.com/oauth2/authorize" profile_url = "https://api.dropbox.com/2/users/get_current_account" def complete_login(self, request, app, token, **kwargs): response = ( get_adapter() .get_requests_session() .post( self.profile_url, headers={"Authorization": "Bearer %s" % (token.token,)}, ) ) response.raise_for_status() return self.get_provider().sociallogin_from_response(request, response.json()) oauth_login = OAuth2LoginView.adapter_view(DropboxOAuth2Adapter) oauth_callback = OAuth2CallbackView.adapter_view(DropboxOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/dummy/000077500000000000000000000000001467545753200241515ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dummy/__init__.py000066400000000000000000000000001467545753200262500ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dummy/forms.py000066400000000000000000000005441467545753200256540ustar00rootroot00000000000000from django import forms class AuthenticateForm(forms.Form): id = forms.IntegerField(label="Account ID") email = forms.EmailField(required=False) email_verified = forms.BooleanField(required=False) username = forms.CharField(required=False) first_name = forms.CharField(required=False) last_name = forms.CharField(required=False) django-allauth-65.0.2/allauth/socialaccount/providers/dummy/provider.py000066400000000000000000000050671467545753200263650ustar00rootroot00000000000000import json from django.http import HttpResponseRedirect from django.urls import reverse from django.utils.http import urlencode from allauth.account.models import EmailAddress from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.base import Provider, ProviderAccount from allauth.socialaccount.providers.dummy.forms import AuthenticateForm class DummyAccount(ProviderAccount): pass class DummyProvider(Provider): id = "dummy" name = "Dummy" account_class = DummyAccount uses_apps = False supports_redirect = True supports_token_authentication = True def get_login_url(self, request, **kwargs): url = reverse("dummy_login") if kwargs: url = url + "?" + urlencode(kwargs) return url def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): ret = {} if data.get("first_name"): ret["first_name"] = data.get("first_name") if data.get("last_name"): ret["last_name"] = data.get("last_name") if data.get("username"): ret["username"] = data.get("username") return ret def redirect(self, request, process, next_url=None, data=None, **kwargs): state_id = self.stash_redirect_state( request, process, next_url=next_url, data=data, **kwargs, ) return HttpResponseRedirect( reverse("dummy_authenticate") + "?" + urlencode({"state": state_id}) ) def extract_email_addresses(self, data): addresses = [] email = data.get("email") if email: email_verified = data.get("email_verified") addresses.append( EmailAddress( email=email, verified=email_verified, primary=True, ) ) return addresses def verify_token(self, request, token): # Our ID token is just a JSON payload that can be handed over # to the `AuthenticateForm`. id_token = token.get("id_token") if id_token: try: data = json.loads(id_token) except json.JSONDecodeError: pass else: form = AuthenticateForm(data=data) if form.is_valid(): return self.sociallogin_from_response(request, form.cleaned_data) raise get_adapter().validation_error("invalid_token") provider_classes = [DummyProvider] django-allauth-65.0.2/allauth/socialaccount/providers/dummy/templates/000077500000000000000000000000001467545753200261475ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dummy/templates/dummy/000077500000000000000000000000001467545753200273025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dummy/templates/dummy/authenticate_form.html000066400000000000000000000015621467545753200336750ustar00rootroot00000000000000{% extends "socialaccount/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block content %} {% element h1 %} Dummy Provider Login {% endelement %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" %} {% trans "Login" %} {% endelement %} {% element button form="cancel-form" type="submit" %} {% trans "Cancel" %} {% endelement %} {% endslot %} {% endelement %}
{% csrf_token %}
{% endblock %} django-allauth-65.0.2/allauth/socialaccount/providers/dummy/tests.py000066400000000000000000000014261467545753200256700ustar00rootroot00000000000000from django.conf import settings from django.contrib.auth import get_user_model from django.urls import reverse from allauth.socialaccount.models import SocialAccount def test_login(client, db): resp = client.post(reverse("dummy_login")) assert resp.status_code == 302 assert resp["location"].startswith(reverse("dummy_authenticate") + "?state=") resp = client.post( resp["location"], {"id": "123", "email": "a@b.com", "email_verified": True}, ) assert resp.status_code == 302 assert resp["location"] == settings.LOGIN_REDIRECT_URL get_user_model().objects.filter(email="a@b.com").exists() socialaccount = SocialAccount.objects.get(uid="123") account = socialaccount.get_provider_account() assert account.to_str() == "a@b.com" django-allauth-65.0.2/allauth/socialaccount/providers/dummy/urls.py000066400000000000000000000003211467545753200255040ustar00rootroot00000000000000from django.urls import path from . import views urlpatterns = [ path("dummy/login/", views.login, name="dummy_login"), path("dummy/authenticate/", views.authenticate, name="dummy_authenticate"), ] django-allauth-65.0.2/allauth/socialaccount/providers/dummy/views.py000066400000000000000000000042761467545753200256710ustar00rootroot00000000000000from django.core.exceptions import PermissionDenied from django.urls import reverse from django.utils.decorators import method_decorator from django.utils.http import urlencode from django.views.generic.edit import FormView from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.models import SocialLogin from allauth.socialaccount.providers.base.constants import AuthError from allauth.socialaccount.providers.base.views import BaseLoginView from allauth.socialaccount.providers.dummy.forms import AuthenticateForm from allauth.socialaccount.providers.dummy.provider import DummyProvider @method_decorator(login_not_required, name="dispatch") class LoginView(BaseLoginView): provider_id = DummyProvider.id login = LoginView.as_view() class AuthenticateView(FormView): form_class = AuthenticateForm template_name = "dummy/authenticate_form.html" @method_decorator(login_not_required) def dispatch(self, request, *args, **kwargs): self.state_id = request.GET.get("state") if not self.state_id: raise PermissionDenied() self.provider = get_adapter().get_provider(self.request, DummyProvider.id) if request.method == "POST" and request.POST.get("action") == "cancel": return render_authentication_error( request, self.provider, error=AuthError.CANCELLED, extra_context={"state_id": self.state_id}, ) return super().dispatch(request, *args, **kwargs) def form_valid(self, form): login = self.provider.sociallogin_from_response(self.request, form.cleaned_data) login.state = SocialLogin.unstash_state(self.request) return complete_social_login(self.request, login) def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) ret["action_url"] = ( reverse("dummy_authenticate") + "?" + urlencode({"state": self.state_id}) ) return ret authenticate = AuthenticateView.as_view() django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/000077500000000000000000000000001467545753200243005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/__init__.py000066400000000000000000000000001467545753200263770ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/models.py000066400000000000000000000000001467545753200261230ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/provider.py000066400000000000000000000013021467545753200265000ustar00rootroot00000000000000"""Provider for Dwolla""" from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.dwolla.views import DwollaOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class DwollaAccount(ProviderAccount): pass class DwollaProvider(OAuth2Provider): """Provider for Dwolla""" id = "dwolla" name = "Dwolla" account_class = DwollaAccount oauth2_adapter_class = DwollaOAuth2Adapter def extract_uid(self, data): return str(data.get("id", None)) def extract_common_fields(self, data): return dict( name=data.get("name"), ) provider_classes = [DwollaProvider] django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/tests.py000066400000000000000000000016031467545753200260140ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import DwollaProvider class DwollaTests(OAuth2TestsMixin, TestCase): provider_id = DwollaProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "id": "123", "_links":{"account":{"href":"http://localhost"}}, "name":"John Doe" }""", ) def get_login_response_json(self, with_refresh_token=True): rt = "" if with_refresh_token: rt = ',"refresh_token": "testrf"' return ( """{ "uid":"weibo", "access_token":"testac", "_links":{"account":{"href":"http://localhost"}} %s }""" % rt ) def get_expected_to_str(self): return "John Doe" django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/urls.py000066400000000000000000000002461467545753200256410ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import DwollaProvider urlpatterns = default_urlpatterns(DwollaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/dwolla/views.py000066400000000000000000000031331467545753200260070ustar00rootroot00000000000000from django.conf import settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) ENVIRONMENTS = { "production": { "auth_url": "https://www.dwolla.com/oauth/v2/authenticate", "token_url": "https://www.dwolla.com/oauth/v2/token", }, "sandbox": { "auth_url": "https://uat.dwolla.com/oauth/v2/authenticate", "token_url": "https://uat.dwolla.com/oauth/v2/token", }, } ENV = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("dwolla", {}) .get("ENVIRONMENT", "production") ) AUTH_URL = ENVIRONMENTS[ENV]["auth_url"] TOKEN_URL = ENVIRONMENTS[ENV]["token_url"] class DwollaOAuth2Adapter(OAuth2Adapter): """Dwolla Views Adapter""" scope_delimiter = "|" provider_id = "dwolla" access_token_url = TOKEN_URL authorize_url = AUTH_URL def complete_login(self, request, app, token, response, **kwargs): resp = ( get_adapter() .get_requests_session() .get( response["_links"]["account"]["href"], headers={ "authorization": "Bearer %s" % token.token, "accept": "application/vnd.dwolla.v1.hal+json", }, ) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(DwollaOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(DwollaOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/edmodo/000077500000000000000000000000001467545753200242655ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/edmodo/__init__.py000066400000000000000000000000001467545753200263640ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/edmodo/provider.py000066400000000000000000000023631467545753200264750ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.edmodo.views import EdmodoOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class EdmodoAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("profile_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") class EdmodoProvider(OAuth2Provider): id = "edmodo" name = "Edmodo" account_class = EdmodoAccount oauth2_adapter_class = EdmodoOAuth2Adapter def get_default_scope(self): return ["basic"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( first_name=data.get("first_name"), last_name=data.get("last_name"), email=data.get("email", ""), ) def extract_extra_data(self, data): ret = dict(data) # NOTE: For backwards compatibility ret["user_type"] = data.get("type") ret["profile_url"] = data.get("url") ret["avatar_url"] = data.get("avatars", {}).get("large") # (end NOTE) return ret provider_classes = [EdmodoProvider] django-allauth-65.0.2/allauth/socialaccount/providers/edmodo/tests.py000066400000000000000000000023471467545753200260070ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import EdmodoProvider class EdmodoTests(OAuth2TestsMixin, TestCase): provider_id = EdmodoProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "url": "https://api.edmodo.com/users/74721257", "id": 74721257, "type": "teacher", "username": "getacclaim-teacher1", "user_title": null, "first_name": "Edmodo Test", "last_name": "Teacher", "time_zone": "America/New_York", "utc_offset": -18000, "locale": "en", "gender": null, "start_level": null, "end_level": null, "about": null, "premium": false, "school": {"url": "https://api.edmodo.com/schools/559253", "id": 559253}, "verified_institution_member": true, "coppa_verified": false, "subjects": null, "avatars": { "small": "https://api.edmodo.com/users/74721257/avatar?type=small&u=670329ncqnf8fxv7tya24byn5", "large": "https://api.edmodo.com/users/74721257/avatar?type=large&u=670329ncqnf8fxv7tya24byn5" }, "email":"test@example.com", "sync_enabled": false } """, ) # noqa def get_expected_to_str(self): return "getacclaim-teacher1" django-allauth-65.0.2/allauth/socialaccount/providers/edmodo/urls.py000066400000000000000000000002461467545753200256260ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import EdmodoProvider urlpatterns = default_urlpatterns(EdmodoProvider) django-allauth-65.0.2/allauth/socialaccount/providers/edmodo/views.py000066400000000000000000000016041467545753200257750ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class EdmodoOAuth2Adapter(OAuth2Adapter): provider_id = "edmodo" access_token_url = "https://api.edmodo.com/oauth/token" authorize_url = "https://api.edmodo.com/oauth/authorize" profile_url = "https://api.edmodo.com/users/me" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(EdmodoOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(EdmodoOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/edx/000077500000000000000000000000001467545753200235765ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/edx/__init__.py000066400000000000000000000000001467545753200256750ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/edx/provider.py000066400000000000000000000017541467545753200260110ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.edx.views import EdxOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class EdxAccount(ProviderAccount): def get_profile_url(self): if self.account.extra_data["profile_image"]["has_image"]: return self.account.extra_data["image_url_full"] class EdxProvider(OAuth2Provider): id = "edx" name = "Edx" account_class = EdxAccount oauth2_adapter_class = EdxOAuth2Adapter def get_default_scope(self): return ["profile"] def extract_uid(self, data): """Extract uid ('id') and ensure it's a str.""" return str(data["username"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), name=data.get("name"), user_id=data.get("user_id"), ) provider_classes = [EdxProvider] django-allauth-65.0.2/allauth/socialaccount/providers/edx/tests.py000066400000000000000000000023201467545753200253070ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import EdxProvider class EdxTests(OAuth2TestsMixin, TestCase): provider_id = EdxProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "username":"krzysztof", "bio":null, "requires_parental_consent":true, "language_proficiencies":[ ], "name":"Krzysztof Hoffmann", "country":null, "social_links":[ ], "is_active":true, "profile_image":{ "image_url_small":"http://draft.navoica.pl/static/images/profiles/default_30.png", "image_url_full":"http://draft.navoica.pl/static/images/profiles/default_500.png", "image_url_large":"http://draft.navoica.pl/static/images/profiles/default_120.png", "image_url_medium":"http://draft.navoica.pl/static/images/profiles/default_50.png", "has_image":false }, "extended_profile":[ ], "year_of_birth":null, "level_of_education":null, "goals":"", "accomplishments_shared":false, "gender":null, "date_joined":"2019-09-21T07:48:31Z", "mailing_address":"", "email":"krzysztof.hoffmann@opi.org.pl", "account_privacy":"private" }""", ) def get_expected_to_str(self): return "krzysztof" django-allauth-65.0.2/allauth/socialaccount/providers/edx/urls.py000066400000000000000000000002401467545753200251310ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import EdxProvider urlpatterns = default_urlpatterns(EdxProvider) django-allauth-65.0.2/allauth/socialaccount/providers/edx/views.py000066400000000000000000000032551467545753200253120ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class EdxOAuth2Adapter(OAuth2Adapter): provider_id = "edx" provider_default_url = "https://edx.org" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("EDX_URL", provider_default_url) access_token_url = "{0}/oauth2/access_token".format(provider_base_url) authorize_url = "{0}/oauth2/authorize/".format(provider_base_url) profile_url = "{0}/api/user/v1/me".format(provider_base_url) account_url = "{0}/api/user/v1/accounts/{1}" supports_state = False redirect_uri_protocol = "https" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} response = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = response.json() if extra_data.get("email", None) is None: response = ( get_adapter() .get_requests_session() .get( self.account_url.format( self.provider_base_url, extra_data["username"] ), headers=headers, ) ) extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(EdxOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(EdxOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/eventbrite/000077500000000000000000000000001467545753200251655ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/eventbrite/__init__.py000066400000000000000000000000001467545753200272640ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/eventbrite/provider.py000066400000000000000000000041631467545753200273750ustar00rootroot00000000000000"""Customise Provider classes for Eventbrite API v3.""" from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.eventbrite.views import ( EventbriteOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class EventbriteAccount(ProviderAccount): """ProviderAccount subclass for Eventbrite.""" def get_avatar_url(self): """Return avatar url.""" return self.account.extra_data["image_id"] def to_str(self): emails = self.account.extra_data.get("emails") if emails: return emails[0]["email"] return super().to_str() class EventbriteProvider(OAuth2Provider): """OAuth2Provider subclass for Eventbrite.""" id = "eventbrite" name = "Eventbrite" account_class = EventbriteAccount oauth2_adapter_class = EventbriteOAuth2Adapter def extract_uid(self, data): """Extract uid ('id') and ensure it's a str.""" return str(data["id"]) def get_default_scope(self): """Ensure scope is null to fit their API.""" return [""] def extract_common_fields(self, data): """Extract fields from a basic user query.""" email = None for curr_email in data.get("emails", []): email = email or curr_email.get("email") if curr_email.get("verified", False) and curr_email.get("primary", False): email = curr_email.get("email") return dict( email=email, id=data.get("id"), name=data.get("name"), first_name=data.get("first_name"), last_name=data.get("last_name"), image_url=data.get("image_url"), ) def extract_email_addresses(self, data): addresses = [] for email in data.get("emails", []): addresses.append( EmailAddress( email=email.get("email"), verified=email.get("verified"), ) ) return addresses provider_classes = [EventbriteProvider] django-allauth-65.0.2/allauth/socialaccount/providers/eventbrite/tests.py000066400000000000000000000015561467545753200267100ustar00rootroot00000000000000"""Test Eventbrite OAuth2 v3 Flow.""" from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import EventbriteProvider class EventbriteTests(OAuth2TestsMixin, TestCase): """Test Class for Eventbrite OAuth2 v3.""" provider_id = EventbriteProvider.id def get_mocked_response(self): """Test authentication with an non-null image_id""" return MockedResponse( 200, """{ "emails": [{ "email": "test@example.com", "verified": true }], "id": "999999999", "name": "Andrew Godwin", "first_name": "Andrew", "last_name": "Godwin", "image_id": "99999999" }""", ) def get_expected_to_str(self): return "test@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/eventbrite/urls.py000066400000000000000000000003321467545753200265220ustar00rootroot00000000000000"""Register urls for EventbriteProvider""" from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import EventbriteProvider urlpatterns = default_urlpatterns(EventbriteProvider) django-allauth-65.0.2/allauth/socialaccount/providers/eventbrite/views.py000066400000000000000000000020231467545753200266710ustar00rootroot00000000000000"""Views for Eventbrite API v3.""" from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class EventbriteOAuth2Adapter(OAuth2Adapter): """OAuth2Adapter for Eventbrite API v3.""" provider_id = "eventbrite" authorize_url = "https://www.eventbrite.com/oauth/authorize" access_token_url = "https://www.eventbrite.com/oauth/token" profile_url = "https://www.eventbriteapi.com/v3/users/me/" def complete_login(self, request, app, token, **kwargs): """Complete login.""" resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"token": token.token}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(EventbriteOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(EventbriteOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/eveonline/000077500000000000000000000000001467545753200250025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/eveonline/__init__.py000066400000000000000000000000001467545753200271010ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/eveonline/provider.py000066400000000000000000000030731467545753200272110ustar00rootroot00000000000000from allauth.socialaccount.app_settings import STORE_TOKENS from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.eveonline.views import ( EveOnlineOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class EveOnlineAccount(ProviderAccount): def get_profile_url(self): return "https://gate.eveonline.com/Profile/{char_name}".format( char_name=self.account.extra_data.get("CharacterName") ) def get_avatar_url(self): return ("https://image.eveonline.com/Character/{char_id}_128.jpg").format( char_id=self.account.extra_data.get("CharacterID", 1) ) def to_str(self): dflt = super(EveOnlineAccount, self).to_str() return next( value for value in ( self.account.extra_data.get("CharacterName", None), self.account.extra_data.get("CharacterID", None), dflt, ) if value is not None ) class EveOnlineProvider(OAuth2Provider): id = "eveonline" name = "EVE Online" account_class = EveOnlineAccount oauth2_adapter_class = EveOnlineOAuth2Adapter def get_default_scope(self): scopes = [] if STORE_TOKENS: scopes.append("publicData") return scopes def extract_uid(self, data): return str(data["CharacterOwnerHash"]) def extract_common_fields(self, data): return dict(name=data.get("CharacterName")) provider_classes = [EveOnlineProvider] django-allauth-65.0.2/allauth/socialaccount/providers/eveonline/tests.py000066400000000000000000000012661467545753200265230ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import EveOnlineProvider class EveOnlineTests(OAuth2TestsMixin, TestCase): provider_id = EveOnlineProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "CharacterID": 273042051, "CharacterName": "CCP illurkall", "ExpiresOn": "2014-05-23T15:01:15.182864Z", "Scopes": " ", "TokenType": "Character", "CharacterOwnerHash": "XM4D...FoY=" }""", ) def get_expected_to_str(self): return "CCP illurkall" django-allauth-65.0.2/allauth/socialaccount/providers/eveonline/urls.py000066400000000000000000000002541467545753200263420ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import EveOnlineProvider urlpatterns = default_urlpatterns(EveOnlineProvider) django-allauth-65.0.2/allauth/socialaccount/providers/eveonline/views.py000066400000000000000000000017401467545753200265130ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class EveOnlineOAuth2Adapter(OAuth2Adapter): provider_id = "eveonline" access_token_url = "https://login.eveonline.com/oauth/token" authorize_url = "https://login.eveonline.com/oauth/authorize" profile_url = "https://login.eveonline.com/oauth/verify" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer " + token.token}, ) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(EveOnlineOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(EveOnlineOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/evernote/000077500000000000000000000000001467545753200246455ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/evernote/__init__.py000066400000000000000000000000001467545753200267440ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/evernote/provider.py000066400000000000000000000013021467545753200270450ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.evernote.views import EvernoteOAuthAdapter from allauth.socialaccount.providers.oauth.provider import OAuthProvider class EvernoteAccount(ProviderAccount): def get_profile_url(self): return None def get_avatar_url(self): return None class EvernoteProvider(OAuthProvider): id = "evernote" name = "Evernote" account_class = EvernoteAccount oauth_adapter_class = EvernoteOAuthAdapter def extract_uid(self, data): return str(data["edam_userId"]) def extract_common_fields(self, data): return data provider_classes = [EvernoteProvider] django-allauth-65.0.2/allauth/socialaccount/providers/evernote/tests.py000066400000000000000000000015651467545753200263700ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import EvernoteProvider class EvernoteTests(OAuthTestsMixin, TestCase): provider_id = EvernoteProvider.id def get_mocked_response(self): return [] def get_expected_to_str(self): return "Evernote" def get_access_token_response(self): return MockedResponse( 200, "oauth_token=S%3Ds1%3AU%3D9876%3AE%3D999999b0c50%3AC%3D14c1f89dd18%3AP%3D81%3AA%3Dpennersr%3AV%3D2%3AH%3Ddeadf00dd2d6aba7b519923987b4bf77&oauth_token_secret=&edam_shard=s1&edam_userId=591969&edam_expires=1457994271824&edam_noteStoreUrl=https%3A%2F%2Fsandbox.evernote.com%2Fshard%2Fs1%2Fnotestore&edam_webApiUrlPrefix=https%3A%2F%2Fsandbox.evernote.com%2Fshard%2Fs1%2F", # noqa {"content-type": "text/plain"}, ) django-allauth-65.0.2/allauth/socialaccount/providers/evernote/urls.py000066400000000000000000000002511467545753200262020ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import EvernoteProvider urlpatterns = default_urlpatterns(EvernoteProvider) django-allauth-65.0.2/allauth/socialaccount/providers/evernote/views.py000066400000000000000000000021301467545753200263500ustar00rootroot00000000000000from datetime import datetime from allauth.socialaccount import app_settings from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class EvernoteOAuthAdapter(OAuthAdapter): provider_id = "evernote" settings = app_settings.PROVIDERS.get(provider_id, {}) request_token_url = "https://%s/oauth" % ( settings.get("EVERNOTE_HOSTNAME", "sandbox.evernote.com") ) access_token_url = "https://%s/oauth" % ( settings.get("EVERNOTE_HOSTNAME", "sandbox.evernote.com") ) authorize_url = "https://%s/OAuth.action" % ( settings.get("EVERNOTE_HOSTNAME", "sandbox.evernote.com") ) def complete_login(self, request, app, token, response): token.expires_at = datetime.fromtimestamp( int(response["edam_expires"]) / 1000.0 ) extra_data = response return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(EvernoteOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(EvernoteOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/exist/000077500000000000000000000000001467545753200241525ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/exist/__init__.py000066400000000000000000000000001467545753200262510ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/exist/provider.py000066400000000000000000000023101467545753200263520ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.exist.views import ExistOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class ExistAccount(ProviderAccount): def get_profile_url(self): return "https://exist.io/api/2/accounts/profile/" def get_avatar_url(self): return self.account.extra_data.get("avatar") class ExistProvider(OAuth2Provider): id = "exist" name = "Exist.io" account_class = ExistAccount oauth2_adapter_class = ExistOAuth2Adapter def extract_uid(self, data): return data.get("username") def extract_common_fields(self, data): extra_common = super().extract_common_fields(data) extra_common.update( username=data.get("username"), first_name=data.get("first_name"), last_name=data.get("last_name"), avatar=data.get("avatar"), timezone=data.get("timezone"), local_time=data.get("local_time"), ) return extra_common def get_default_scope(self): return ["mood_read", "health_read", "productivity_read"] provider_classes = [ExistProvider] django-allauth-65.0.2/allauth/socialaccount/providers/exist/tests.py000066400000000000000000000023201467545753200256630ustar00rootroot00000000000000from allauth.socialaccount.providers.exist.provider import ExistProvider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class ExistTests(OAuth2TestsMixin, TestCase): provider_id = ExistProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "id": 1, "username": "josh", "first_name": "Josh", "last_name": "Sharp", "bio": "I made this thing you're using.", "url": "http://hellocode.co/", "avatar": "https://exist.io/static/media/avatars/josh_2.png", "timezone": "Australia/Melbourne", "local_time": "2020-07-31T22:33:49.359+10:00", "private": false, "imperial_units": false, "imperial_distance": false, "imperial_weight": false, "imperial_energy": false, "imperial_liquid": false, "imperial_temperature": false, "attributes": [] } """, ) def get_expected_to_str(self): return "josh" django-allauth-65.0.2/allauth/socialaccount/providers/exist/urls.py000066400000000000000000000002441467545753200255110ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import ExistProvider urlpatterns = default_urlpatterns(ExistProvider) django-allauth-65.0.2/allauth/socialaccount/providers/exist/views.py000066400000000000000000000016351467545753200256660ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class ExistOAuth2Adapter(OAuth2Adapter): provider_id = "exist" access_token_url = "https://exist.io/oauth2/access_token" authorize_url = "https://exist.io/oauth2/authorize" profile_url = "https://exist.io/api/2/accounts/profile/" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(ExistOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(ExistOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/facebook/000077500000000000000000000000001467545753200245675ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/__init__.py000066400000000000000000000000001467545753200266660ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/constants.py000066400000000000000000000006661467545753200271650ustar00rootroot00000000000000from django.conf import settings PROVIDER_ID = "facebook" GRAPH_API_VERSION = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("facebook", {}) .get("VERSION", "v19.0") ) GRAPH_API_URL = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("facebook", {}) .get("GRAPH_API_URL", "https://graph.facebook.com/{}".format(GRAPH_API_VERSION)) ) NONCE_SESSION_KEY = "allauth_facebook_nonce" NONCE_LENGTH = 32 django-allauth-65.0.2/allauth/socialaccount/providers/facebook/data/000077500000000000000000000000001467545753200255005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/data/FacebookLocales.xml000066400000000000000000000311061467545753200312370ustar00rootroot00000000000000 Afrikaans FB af_ZA Arabic FB ar_AR Azerbaijani FB az_AZ Belarusian FB be_BY Bulgarian FB bg_BG Bengali FB bn_IN Bosnian FB bs_BA Catalan FB ca_ES Czech FB cs_CZ Welsh FB cy_GB Danish FB da_DK German FB de_DE Greek FB el_GR English (UK) FB en_GB English (Pirate) FB en_PI English (Upside Down) FB en_UD English (US) FB en_US Esperanto FB eo_EO Spanish (Spain) FB es_ES Spanish FB es_LA Estonian FB et_EE Basque FB eu_ES Persian FB fa_IR Leet Speak FB fb_LT Finnish FB fi_FI Faroese FB fo_FO French (Canada) FB fr_CA French (France) FB fr_FR Frisian FB fy_NL Irish FB ga_IE Galician FB gl_ES Hebrew FB he_IL Hindi FB hi_IN Croatian FB hr_HR Hungarian FB hu_HU Armenian FB hy_AM Indonesian FB id_ID Icelandic FB is_IS Italian FB it_IT Japanese FB ja_JP Georgian FB ka_GE Khmer FB km_KH Korean FB ko_KR Kurdish FB ku_TR Latin FB la_VA Lithuanian FB lt_LT Latvian FB lv_LV Macedonian FB mk_MK Malayalam FB ml_IN Malay FB ms_MY Norwegian (bokmal) FB nb_NO Nepali FB ne_NP Dutch FB nl_NL Norwegian (nynorsk) FB nn_NO Punjabi FB pa_IN Polish FB pl_PL Pashto FB ps_AF Portuguese (Brazil) FB pt_BR Portuguese (Portugal) FB pt_PT Romanian FB ro_RO Russian FB ru_RU Slovak FB sk_SK Slovenian FB sl_SI Albanian FB sq_AL Serbian FB sr_RS Swedish FB sv_SE Swahili FB sw_KE Tamil FB ta_IN Telugu FB te_IN Thai FB th_TH Filipino FB tl_PH Turkish FB tr_TR Ukrainian FB uk_UA Vietnamese FB vi_VN Simplified Chinese (China) FB zh_CN Traditional Chinese (Hong Kong) FB zh_HK Traditional Chinese (Taiwan) FB zh_TW django-allauth-65.0.2/allauth/socialaccount/providers/facebook/flows.py000066400000000000000000000104551467545753200263000ustar00rootroot00000000000000import hashlib import hmac from datetime import timedelta from django.core.cache import cache from django.utils import timezone from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialLogin, SocialToken from allauth.socialaccount.providers.base import Provider from allauth.socialaccount.providers.facebook.constants import GRAPH_API_URL def compute_appsecret_proof(app, token): # Generate an appsecret_proof parameter to secure the Graph API call # see https://developers.facebook.com/docs/graph-api/securing-requests msg = token.token.encode("utf-8") key = app.secret.encode("utf-8") appsecret_proof = hmac.new(key, msg, digestmod=hashlib.sha256).hexdigest() return appsecret_proof def complete_login(request, provider, token): resp = ( get_adapter() .get_requests_session() .get( GRAPH_API_URL + "/me", params={ "fields": ",".join(provider.get_fields()), "access_token": token.token, "appsecret_proof": compute_appsecret_proof(provider.app, token), }, ) ) resp.raise_for_status() extra_data = resp.json() login = provider.sociallogin_from_response(request, extra_data) return login def get_app_token(provider): app = provider.app cache_key = f"allauth.facebook.app_token[{app.client_id}]" app_token = cache.get(cache_key) if not app_token: resp = ( get_adapter() .get_requests_session() .get( GRAPH_API_URL + "/oauth/access_token", params={ "client_id": app.client_id, "client_secret": app.secret, "grant_type": "client_credentials", }, ) ) resp.raise_for_status() data = resp.json() app_token = data["access_token"] timeout = provider.get_settings().get("APP_TOKEN_CACHE_TIMEOUT", 300) cache.set(cache_key, app_token, timeout=timeout) return app_token def inspect_token(provider, input_token): app_token = get_app_token(provider) resp = ( get_adapter() .get_requests_session() .get( GRAPH_API_URL + "/debug_token", params={"input_token": input_token, "access_token": app_token}, ) ) resp.raise_for_status() data = resp.json()["data"] if not data["is_valid"]: raise get_adapter().validation_error("invalid_token") if data["app_id"] != provider.app.client_id or not data["is_valid"]: raise get_adapter().validation_error("invalid_token") def verify_token( request, provider: Provider, access_token: str, auth_type: str = "", auth_nonce: str = "", ) -> SocialLogin: app = provider.app inspect_token(provider, access_token) expires_at = None if auth_type == "reauthenticate": resp = ( get_adapter() .get_requests_session() .get( GRAPH_API_URL + "/oauth/access_token_info", params={ "client_id": app.client_id, "access_token": access_token, }, ) ) resp.raise_for_status() info = resp.json() ok = auth_nonce and auth_nonce == info.get("auth_nonce") if not ok: raise get_adapter().validation_error("invalid_token") if provider.get_settings().get("EXCHANGE_TOKEN"): resp = ( get_adapter() .get_requests_session() .get( GRAPH_API_URL + "/oauth/access_token", params={ "grant_type": "fb_exchange_token", "client_id": app.client_id, "client_secret": app.secret, "fb_exchange_token": access_token, }, ) ) resp.raise_for_status() info = resp.json() access_token = info["access_token"] expires_in = info.get("expires_in") if expires_in: expires_at = timezone.now() + timedelta(seconds=int(expires_in)) token = SocialToken(app=app, token=access_token, expires_at=expires_at) login = complete_login(request, provider, token) login.token = token return login django-allauth-65.0.2/allauth/socialaccount/providers/facebook/forms.py000066400000000000000000000001641467545753200262700ustar00rootroot00000000000000from django import forms class FacebookConnectForm(forms.Form): access_token = forms.CharField(required=True) django-allauth-65.0.2/allauth/socialaccount/providers/facebook/locale.py000066400000000000000000000045361467545753200264100ustar00rootroot00000000000000# Default locale mapping for the Facebook JS SDK # The list of supported locales is at # https://www.facebook.com/translations/FacebookLocales.xml import os from django.utils.translation import get_language, to_locale def _build_locale_table(filename_or_file): """ Parses the FacebookLocales.xml file and builds a dict relating every available language ('en, 'es, 'zh', ...) with a list of available regions for that language ('en' -> 'US', 'EN') and an (arbitrary) default region. """ # Require the XML parser module only if we want the default mapping from xml.dom.minidom import parse dom = parse(filename_or_file) reps = dom.getElementsByTagName("representation") locs = map(lambda r: r.childNodes[0].data, reps) locale_map = {} for loc in locs: lang, _, reg = loc.partition("_") lang_map = locale_map.setdefault(lang, {"regs": [], "default": reg}) lang_map["regs"].append(reg) # Default region overrides (arbitrary) locale_map["en"]["default"] = "US" # Special case: Use es_ES for Spain and es_LA for everything else locale_map["es"]["default"] = "LA" locale_map["zh"]["default"] = "CN" locale_map["fr"]["default"] = "FR" locale_map["pt"]["default"] = "PT" return locale_map def get_default_locale_callable(): """ Wrapper function so that the default mapping is only built when needed """ exec_dir = os.path.dirname(os.path.realpath(__file__)) xml_path = os.path.join(exec_dir, "data", "FacebookLocales.xml") fb_locales = _build_locale_table(xml_path) def default_locale(request): """ Guess an appropriate FB locale based on the active Django locale. If the active locale is available, it is returned. Otherwise, it tries to return another locale with the same language. If there isn't one available, 'en_US' is returned. """ chosen = "en_US" language = get_language() if language: locale = to_locale(language) lang, _, reg = locale.partition("_") lang_map = fb_locales.get(lang) if lang_map is not None: if reg in lang_map["regs"]: chosen = lang + "_" + reg else: chosen = lang + "_" + lang_map["default"] return chosen return default_locale django-allauth-65.0.2/allauth/socialaccount/providers/facebook/provider.py000066400000000000000000000171421467545753200270000ustar00rootroot00000000000000import requests import string from urllib.parse import quote from django.contrib.auth import REDIRECT_FIELD_NAME from django.middleware.csrf import get_token from django.template.loader import render_to_string from django.urls import reverse from django.utils.crypto import get_random_string from django.utils.html import escapejs from allauth.account.models import EmailAddress from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.base import ( AuthAction, AuthProcess, ProviderAccount, ) from allauth.socialaccount.providers.facebook.constants import ( GRAPH_API_URL, GRAPH_API_VERSION, NONCE_LENGTH, NONCE_SESSION_KEY, PROVIDER_ID, ) from allauth.socialaccount.providers.facebook.views import ( FacebookOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.utils import import_callable from .locale import get_default_locale_callable class FacebookAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("link") def get_avatar_url(self): uid = self.account.uid # ask for a 600x600 pixel image. We might get smaller but # image will always be highest res possible and square return ( GRAPH_API_URL + "/%s/picture?type=square&height=600&width=600&return_ssl_resources=1" % uid ) # noqa class FacebookProvider(OAuth2Provider): id = PROVIDER_ID name = "Facebook" account_class = FacebookAccount oauth2_adapter_class = FacebookOAuth2Adapter supports_token_authentication = True def __init__(self, *args, **kwargs): self._locale_callable_cache = None super().__init__(*args, **kwargs) def get_method(self): return self.get_settings().get("METHOD", "oauth2") def get_login_url(self, request, **kwargs): method = kwargs.pop("method", self.get_method()) if method == "js_sdk": next = "'%s'" % escapejs(kwargs.get(REDIRECT_FIELD_NAME) or "") process = "'%s'" % escapejs(kwargs.get("process") or AuthProcess.LOGIN) action = "'%s'" % escapejs(kwargs.get("action") or AuthAction.AUTHENTICATE) scope = "'%s'" % escapejs(kwargs.get("scope", "")) js = "allauth.facebook.login(%s, %s, %s, %s)" % ( next, action, process, scope, ) ret = "javascript:%s" % (quote(js),) elif method == "oauth2": ret = super(FacebookProvider, self).get_login_url(request, **kwargs) else: raise RuntimeError("Invalid method specified: %s" % method) return ret def _get_locale_callable(self): settings = self.get_settings() func = settings.get("LOCALE_FUNC") return import_callable(func) if func else get_default_locale_callable() def get_locale_for_request(self, request): if not self._locale_callable_cache: self._locale_callable_cache = self._get_locale_callable() return self._locale_callable_cache(request) def get_default_scope(self): scope = [] if QUERY_EMAIL: scope.append("email") return scope def get_fields(self): settings = self.get_settings() default_fields = [ "id", "email", "name", "first_name", "last_name", "verified", "locale", "timezone", "link", "gender", "updated_time", ] return settings.get("FIELDS", default_fields) def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["auth_type"] = "reauthenticate" elif action == AuthAction.REREQUEST: ret["auth_type"] = "rerequest" return ret def get_init_params(self, request, app): init_params = {"appId": app.client_id, "version": GRAPH_API_VERSION} settings = self.get_settings() init_params.update(settings.get("INIT_PARAMS", {})) return init_params def get_fb_login_options(self, request): ret = self.get_auth_params_from_request(request, "authenticate") ret["scope"] = ",".join(self.get_scope_from_request(request)) if ret.get("auth_type") == "reauthenticate": ret["auth_nonce"] = self.get_nonce(request, or_create=True) return ret def get_sdk_url(self, request): settings = self.get_settings() sdk_url = settings.get("SDK_URL", "//connect.facebook.net/{locale}/sdk.js") field_names = [ tup[1] for tup in string.Formatter().parse(sdk_url) if tup[1] is not None ] if "locale" in field_names: locale = self.get_locale_for_request(request) sdk_url = sdk_url.format(locale=locale) return sdk_url def media_js(self, request): if self.get_method() != "js_sdk": return "" def abs_uri(name): return request.build_absolute_uri(reverse(name)) fb_data = { "appId": self.app.client_id, "version": GRAPH_API_VERSION, "sdkUrl": self.get_sdk_url(request), "initParams": self.get_init_params(request, self.app), "loginOptions": self.get_fb_login_options(request), "loginByTokenUrl": abs_uri("facebook_login_by_token"), "cancelUrl": abs_uri("socialaccount_login_cancelled"), "logoutUrl": abs_uri("account_logout"), "loginUrl": request.build_absolute_uri( self.get_login_url(request, method="oauth2") ), "errorUrl": abs_uri("socialaccount_login_error"), "csrfToken": get_token(request), } ctx = {"fb_data": fb_data} return render_to_string("facebook/fbconnect.html", ctx, request=request) def get_nonce(self, request, or_create=False, pop=False): if pop: nonce = request.session.pop(NONCE_SESSION_KEY, None) else: nonce = request.session.get(NONCE_SESSION_KEY) if not nonce and or_create: nonce = get_random_string(NONCE_LENGTH) request.session[NONCE_SESSION_KEY] = nonce return nonce def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), first_name=data.get("first_name"), last_name=data.get("last_name"), name=data.get("name"), ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: # data['verified'] does not imply the email address is # verified. ret.append(EmailAddress(email=email, verified=False, primary=True)) return ret def verify_token(self, request, token): from allauth.socialaccount.providers.facebook import flows access_token = token.get("access_token") if not access_token: raise get_adapter().validation_error("invalid_token") try: login = flows.verify_token(request, self, access_token) except (OAuth2Error, requests.RequestException) as e: raise get_adapter().validation_error("invalid_token") from e return login provider_classes = [FacebookProvider] django-allauth-65.0.2/allauth/socialaccount/providers/facebook/static/000077500000000000000000000000001467545753200260565ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/static/facebook/000077500000000000000000000000001467545753200276275ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/static/facebook/js/000077500000000000000000000000001467545753200302435ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/static/facebook/js/fbconnect.js000066400000000000000000000064461467545753200325540ustar00rootroot00000000000000/* global document, window, FB */ (function () { 'use strict' function postForm (action, data) { const f = document.createElement('form') f.method = 'POST' f.action = action for (const key in data) { const d = document.createElement('input') d.type = 'hidden' d.name = key d.value = data[key] f.appendChild(d) } document.body.appendChild(f) f.submit() } function setLocationHref (url) { if (typeof (url) === 'function') { // Deprecated -- instead, override // allauth.facebook.onLoginError et al directly. url() } else { window.location.href = url } } const allauth = window.allauth = window.allauth || {} const fbSettings = JSON.parse(document.getElementById('allauth-facebook-settings').textContent) let fbInitialized = false allauth.facebook = { init: function (opts) { this.opts = opts window.fbAsyncInit = function () { FB.init(opts.initParams) fbInitialized = true allauth.facebook.onInit() }; (function (d) { const id = 'facebook-jssdk' if (d.getElementById(id)) { return } const js = d.createElement('script'); js.id = id; js.async = true js.src = opts.sdkUrl d.getElementsByTagName('head')[0].appendChild(js) }(document)) }, onInit: function () { }, login: function (nextUrl, action, process, scope) { const self = this if (!fbInitialized) { const url = this.opts.loginUrl + '?next=' + encodeURIComponent(nextUrl) + '&action=' + encodeURIComponent(action) + '&process=' + encodeURIComponent(process) + '&scope=' + encodeURIComponent(scope) setLocationHref(url) return } if (action === 'reauthenticate' || action === 'rerequest') { this.opts.loginOptions.auth_type = action } if (scope !== '') { this.opts.loginOptions.scope = scope } FB.login(function (response) { if (response.authResponse) { self.onLoginSuccess(response, nextUrl, process) } else if (response && response.status && ['not_authorized', 'unknown'].indexOf(response.status) > -1) { self.onLoginCanceled(response) } else { self.onLoginError(response) } }, self.opts.loginOptions) }, onLoginCanceled: function (/* response */) { setLocationHref(this.opts.cancelUrl) }, onLoginError: function (/* response */) { setLocationHref(this.opts.errorUrl) }, onLoginSuccess: function (response, nextUrl, process) { const data = { next: nextUrl || '', process, access_token: response.authResponse.accessToken, expires_in: response.authResponse.expiresIn, csrfmiddlewaretoken: this.opts.csrfToken } postForm(this.opts.loginByTokenUrl, data) }, logout: function (nextUrl) { const self = this if (!fbInitialized) { return } FB.logout(function (response) { self.onLogoutSuccess(response, nextUrl) }) }, onLogoutSuccess: function (response, nextUrl) { const data = { next: nextUrl || '', csrfmiddlewaretoken: this.opts.csrfToken } postForm(this.opts.logoutUrl, data) } } allauth.facebook.init(fbSettings) })() django-allauth-65.0.2/allauth/socialaccount/providers/facebook/templates/000077500000000000000000000000001467545753200265655ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/templates/facebook/000077500000000000000000000000001467545753200303365ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/facebook/templates/facebook/fbconnect.html000066400000000000000000000002411467545753200331620ustar00rootroot00000000000000{% load static %}
{{ fb_data|json_script:"allauth-facebook-settings" }} django-allauth-65.0.2/allauth/socialaccount/providers/facebook/tests.py000066400000000000000000000131611467545753200263050ustar00rootroot00000000000000from django.contrib.auth import get_user_model from django.test.client import RequestFactory from django.test.utils import override_settings from django.urls import reverse from allauth.account import app_settings as account_settings from allauth.account.models import EmailAddress from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .provider import FacebookProvider @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=True, ACCOUNT_SIGNUP_FORM_CLASS=None, LOGIN_REDIRECT_URL="/accounts/profile/", ACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.NONE, SOCIALACCOUNT_PROVIDERS={"facebook": {"AUTH_PARAMS": {}, "VERIFIED_EMAIL": False}}, ) class FacebookTests(OAuth2TestsMixin, TestCase): provider_id = FacebookProvider.id facebook_data = """ { "id": "630595557", "name": "Raymond Penners", "first_name": "Raymond", "last_name": "Penners", "email": "raymond.penners@example.com", "link": "https://www.facebook.com/raymond.penners", "username": "raymond.penners", "birthday": "07/17/1973", "work": [ { "employer": { "id": "204953799537777", "name": "IntenCT" } } ], "timezone": 1, "locale": "nl_NL", "verified": true, "updated_time": "2012-11-30T20:40:33+0000" }""" def get_mocked_response(self, data=None): if data is None: data = self.facebook_data return MockedResponse(200, data) def get_expected_to_str(self): return "raymond.penners" def test_username_conflict(self): User = get_user_model() User.objects.create(username="raymond.penners") self.login(self.get_mocked_response()) socialaccount = SocialAccount.objects.get(uid="630595557") self.assertEqual(socialaccount.user.username, "raymond") def test_username_based_on_provider(self): self.login(self.get_mocked_response()) socialaccount = SocialAccount.objects.get(uid="630595557") self.assertEqual(socialaccount.user.username, "raymond.penners") def test_username_based_on_provider_with_simple_name(self): data = '{"id": "1234567", "name": "Harvey McGillicuddy"}' self.login(self.get_mocked_response(data=data)) socialaccount = SocialAccount.objects.get(uid="1234567") self.assertEqual(socialaccount.user.username, "harvey") @override_settings( SOCIALACCOUNT_PROVIDERS={ "facebook": { "METHOD": "js_sdk", } }, ) def test_media_js(self): request = RequestFactory().get(reverse("account_login")) request.session = {} script = self.provider.media_js(request) self.assertTrue('"appId": "app123id"' in script) def test_token_auth(self): with mocked_response( {"access_token": "app_token"}, { "data": { "app_id": "app123id", "is_valid": True, } }, self.get_mocked_response(), ): login = self.provider.verify_token(None, {"access_token": "dummy"}) assert login.user.email == "raymond.penners@example.com" assert login.token.token == "dummy" def test_login_by_token(self): resp = self.client.get(reverse("account_login")) with mocked_response( {"access_token": "app_token"}, { "data": { "app_id": "app123id", "is_valid": True, } }, self.get_mocked_response(), ): resp = self.client.post( reverse("facebook_login_by_token"), data={"access_token": "dummy"}, ) self.assertRedirects( resp, "/accounts/profile/", fetch_redirect_response=False ) @override_settings( SOCIALACCOUNT_PROVIDERS={ "facebook": { "METHOD": "js_sdk", "AUTH_PARAMS": {"auth_type": "reauthenticate"}, "VERIFIED_EMAIL": False, } } ) def test_login_by_token_reauthenticate(self): resp = self.client.get(reverse("account_login")) nonce = resp.context["fb_data"]["loginOptions"]["auth_nonce"] with mocked_response( {"access_token": "app_token"}, { "data": { "app_id": "app123id", "is_valid": True, } }, {"auth_nonce": nonce}, self.get_mocked_response(), ): resp = self.client.post( reverse("facebook_login_by_token"), data={"access_token": "dummy"}, ) self.assertRedirects( resp, "/accounts/profile/", fetch_redirect_response=False ) @override_settings(SOCIALACCOUNT_PROVIDERS={"facebook": {"VERIFIED_EMAIL": True}}) def test_login_verified(self): emailaddress = self._login_verified() self.assertTrue(emailaddress.verified) def test_login_unverified(self): emailaddress = self._login_verified() self.assertFalse(emailaddress.verified) def _login_verified(self): self.login(self.get_mocked_response()) return EmailAddress.objects.get(email="raymond.penners@example.com") django-allauth-65.0.2/allauth/socialaccount/providers/facebook/urls.py000066400000000000000000000005501467545753200261260ustar00rootroot00000000000000from django.urls import path from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from . import views from .provider import FacebookProvider urlpatterns = default_urlpatterns(FacebookProvider) urlpatterns += [ path( "facebook/login/token/", views.login_by_token, name="facebook_login_by_token", ), ] django-allauth-65.0.2/allauth/socialaccount/providers/facebook/views.py000066400000000000000000000062261467545753200263040ustar00rootroot00000000000000import logging import requests from django import forms from django.core.exceptions import PermissionDenied from django.utils.decorators import method_decorator from django.views.generic import View from allauth.account.internal.decorators import login_not_required from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.models import SocialLogin from allauth.socialaccount.providers.facebook import flows from allauth.socialaccount.providers.facebook.constants import ( GRAPH_API_URL, GRAPH_API_VERSION, PROVIDER_ID, ) from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .forms import FacebookConnectForm logger = logging.getLogger(__name__) class FacebookOAuth2Adapter(OAuth2Adapter): provider_id = PROVIDER_ID provider_default_auth_url = "https://www.facebook.com/{}/dialog/oauth".format( GRAPH_API_VERSION ) settings = app_settings.PROVIDERS.get(provider_id, {}) scope_delimiter = "," authorize_url = settings.get("AUTHORIZE_URL", provider_default_auth_url) access_token_url = GRAPH_API_URL + "/oauth/access_token" access_token_method = "GET" expires_in_key = "expires_in" def complete_login(self, request, app, access_token, **kwargs): provider = self.get_provider() return flows.complete_login(request, provider, access_token) oauth2_login = OAuth2LoginView.adapter_view(FacebookOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FacebookOAuth2Adapter) class LoginByTokenView(View): @method_decorator(login_not_required) def dispatch(self, request): self.adapter = get_adapter() self.provider = self.adapter.get_provider(request, PROVIDER_ID) try: return super().dispatch(request) except ( requests.RequestException, forms.ValidationError, PermissionDenied, ) as exc: return render_authentication_error(request, self.provider, exception=exc) def get(self, request): # If we leave out get().get() it will return a response with a 405, but # we really want to show an authentication error. raise PermissionDenied("405") def post(self, request): form = FacebookConnectForm(request.POST) if not form.is_valid(): raise self.adapter.validation_error("invalid_token") access_token = form.cleaned_data["access_token"] provider = self.provider login_options = provider.get_fb_login_options(request) auth_type = login_options.get("auth_type") auth_nonce = "" if auth_type == "reauthenticate": auth_nonce = provider.get_nonce(request, pop=True) login = flows.verify_token( request, provider, access_token, auth_type, auth_nonce ) login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) return ret login_by_token = LoginByTokenView.as_view() django-allauth-65.0.2/allauth/socialaccount/providers/feedly/000077500000000000000000000000001467545753200242665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/feedly/__init__.py000066400000000000000000000000001467545753200263650ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/feedly/provider.py000066400000000000000000000016031467545753200264720ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.feedly.views import FeedlyOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class FeedlyAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("picture") class FeedlyProvider(OAuth2Provider): id = "feedly" name = "Feedly" account_class = FeedlyAccount oauth2_adapter_class = FeedlyOAuth2Adapter def get_default_scope(self): return ["https://cloud.feedly.com/subscriptions"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), last_name=data.get("familyName"), first_name=data.get("givenName"), ) provider_classes = [FeedlyProvider] django-allauth-65.0.2/allauth/socialaccount/providers/feedly/tests.py000066400000000000000000000014401467545753200260010ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FeedlyProvider class FeedlyTests(OAuth2TestsMixin, TestCase): provider_id = FeedlyProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "id": "c805fcbf-3acf-4302-a97e-d82f9d7c897f", "email": "jim.smith@example.com", "givenName": "Jim", "familyName": "Smith", "picture": "https://www.google.com/profile_images/1771656873/bigger.jpg", "gender": "male", "locale": "en", "reader": "9080770707070700", "google": "115562565652656565656", "twitter": "jimsmith", "facebook": "", "wave": "2013.7" }""", ) def get_expected_to_str(self): return "jim.smith@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/feedly/urls.py000066400000000000000000000002461467545753200256270ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import FeedlyProvider urlpatterns = default_urlpatterns(FeedlyProvider) django-allauth-65.0.2/allauth/socialaccount/providers/feedly/views.py000066400000000000000000000020221467545753200257710ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class FeedlyOAuth2Adapter(OAuth2Adapter): provider_id = "feedly" host = app_settings.PROVIDERS.get(provider_id, {}).get("HOST", "cloud.feedly.com") access_token_url = "https://%s/v3/auth/token" % host authorize_url = "https://%s/v3/auth/auth" % host profile_url = "https://%s/v3/profile" % host def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "OAuth {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(FeedlyOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FeedlyOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/feishu/000077500000000000000000000000001467545753200243015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/feishu/__init__.py000066400000000000000000000000001467545753200264000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/feishu/client.py000066400000000000000000000054221467545753200261340ustar00rootroot00000000000000import json from collections import OrderedDict from django.utils.http import urlencode from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) class FeishuOAuth2Client(OAuth2Client): app_access_token_url = ( "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/" ) def get_redirect_url(self, authorization_url, scope, extra_params): scope = self.scope_delimiter.join(set(scope)) params = { "app_id": self.consumer_key, "redirect_uri": self.callback_url, "scope": scope, "response_type": "code", } if self.state: params["state"] = self.state params.update(extra_params) sorted_params = OrderedDict() for param in sorted(params): sorted_params[param] = params[param] return "%s?%s" % (authorization_url, urlencode(sorted_params)) def app_access_token(self): data = { "app_id": self.consumer_key, "app_secret": self.consumer_secret, } self._strip_empty_keys(data) url = self.app_access_token_url # TODO: Proper exception handling resp = get_adapter().get_requests_session().request("POST", url, data=data) resp.raise_for_status() access_token = resp.json() if not access_token or "app_access_token" not in access_token: raise OAuth2Error("Error retrieving app access token: %s" % resp.content) return access_token["app_access_token"] def get_access_token(self, code, pkce_code_verifier=None): data = { "grant_type": "authorization_code", "code": code, "app_access_token": self.app_access_token(), } params = None self._strip_empty_keys(data) url = self.access_token_url if self.access_token_method == "GET": params = data data = None if data and pkce_code_verifier: data["code_verifier"] = pkce_code_verifier # TODO: Proper exception handling resp = ( get_adapter() .get_requests_session() .request( self.access_token_method, url, params=params, data=json.dumps(data), headers={"Content-Type": "application/json"}, ) ) resp.raise_for_status() access_token = resp.json() if ( not access_token or "data" not in access_token or "access_token" not in access_token["data"] ): raise OAuth2Error("Error retrieving access token: %s" % resp.content) return access_token["data"] django-allauth-65.0.2/allauth/socialaccount/providers/feishu/provider.py000066400000000000000000000013201467545753200265010ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.feishu.views import FeishuOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class FeishuAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("avatar_big") class FeishuProvider(OAuth2Provider): id = "feishu" name = "feishu" account_class = FeishuAccount oauth2_adapter_class = FeishuOAuth2Adapter def extract_uid(self, data): return data["open_id"] def extract_common_fields(self, data): return dict(username=data.get("name"), name=data.get("name")) provider_classes = [FeishuProvider] django-allauth-65.0.2/allauth/socialaccount/providers/feishu/tests.py000066400000000000000000000031721467545753200260200ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FeishuProvider class FeishuTests(OAuth2TestsMixin, TestCase): provider_id = FeishuProvider.id def get_mocked_response(self): return [ MockedResponse( 0, """ {"data": {"access_token": "testac"}} """, ), MockedResponse( 0, """ { "code": 0, "data": { "access_token": "u-6U1SbDiM6XIH2DcTCPyeub", "avatar_url": "www.feishu.cn/avatar/icon", "avatar_thumb": "www.feishu.cn/avatar/icon_thumb", "avatar_middle": "www.feishu.cn/avatar/icon_middle", "avatar_big": "www.feishu.cn/avatar/icon_big", "expires_in": 7140, "name": "zhangsan", "en_name": "Three Zhang", "open_id": "ou-caecc734c2e3328a62489fe0648c4b98779515d3", "tenant_key": "736588c92lxf175d", "refresh_expires_in": 2591940, "refresh_token": "ur-t9HHgRCjMqGqIU9v05Zhos", "token_type": "Bearer" } } """, ), ] def get_expected_to_str(self): return "zhangsan" def get_login_response_json(self, with_refresh_token=True): return """{"app_access_token":"testac"}""" django-allauth-65.0.2/allauth/socialaccount/providers/feishu/urls.py000066400000000000000000000002461467545753200256420ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import FeishuProvider urlpatterns = default_urlpatterns(FeishuProvider) django-allauth-65.0.2/allauth/socialaccount/providers/feishu/views.py000066400000000000000000000044431467545753200260150ustar00rootroot00000000000000from django.urls import reverse from allauth.account import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from allauth.utils import build_absolute_uri from .client import FeishuOAuth2Client class FeishuOAuth2Adapter(OAuth2Adapter): provider_id = "feishu" authorization_url = "https://open.feishu.cn/open-apis/authen/v1/index" access_token_url = "https://open.feishu.cn/open-apis/authen/v1/access_token" app_access_token_url = ( "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/" ) user_info_url = "https://open.feishu.cn/open-apis/authen/v1/user_info" @property def authorize_url(self): settings = self.get_provider().get_settings() url = settings.get("AUTHORIZE_URL", self.authorization_url) return url def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.user_info_url, headers={ "Content-Type": "application/json", "Authorization": "Bearer " + token.token, }, ) ) resp.raise_for_status() extra_data = resp.json() if extra_data["code"] != 0: raise OAuth2Error("Error retrieving code: %s" % resp.content) extra_data = extra_data["data"] return self.get_provider().sociallogin_from_response(request, extra_data) def get_client(self, request, app): callback_url = reverse(self.provider_id + "_callback") protocol = self.redirect_uri_protocol or app_settings.DEFAULT_HTTP_PROTOCOL callback_url = build_absolute_uri(request, callback_url, protocol=protocol) client = FeishuOAuth2Client( request, app.client_id, app.secret, self.access_token_method, self.access_token_url, callback_url, ) return client oauth2_login = OAuth2LoginView.adapter_view(FeishuOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FeishuOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/figma/000077500000000000000000000000001467545753200241015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/figma/__init__.py000066400000000000000000000000001467545753200262000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/figma/provider.py000066400000000000000000000020311467545753200263010ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount import providers from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.figma.views import FigmaOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class FigmaAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("img_url", "") class FigmaProvider(OAuth2Provider): id = "figma" name = "Figma" account_class = FigmaAccount oauth2_adapter_class = FigmaOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return { "email": data.get("email"), "name": data.get("handle"), } def extract_email_addresses(self, data): email = EmailAddress( email=data.get("email"), primary=True, verified=False, ) return [email] providers.registry.register(FigmaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/figma/tests.py000066400000000000000000000012001467545753200256060ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FigmaProvider class FigmaTests(OAuth2TestsMixin, TestCase): provider_id = FigmaProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "id": "2600", "email": "johndoe@example.com", "handle": "John Doe", "img_url": "https://www.example.com/image.png" } """, ) def get_expected_to_str(self): return "John Doe" django-allauth-65.0.2/allauth/socialaccount/providers/figma/urls.py000066400000000000000000000002441467545753200254400ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import FigmaProvider urlpatterns = default_urlpatterns(FigmaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/figma/views.py000066400000000000000000000017351467545753200256160ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class FigmaOAuth2Adapter(OAuth2Adapter): provider_id = "figma" authorize_url = "https://www.figma.com/oauth" access_token_url = "https://www.figma.com/api/oauth/token" userinfo_url = "https://api.figma.com/v1/me" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.userinfo_url, headers={"Authorization": "Bearer {0}".format(token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(FigmaOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FigmaOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/000077500000000000000000000000001467545753200256715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/__init__.py000066400000000000000000000000001467545753200277700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/models.py000066400000000000000000000000001467545753200275140ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/provider.py000066400000000000000000000021501467545753200300730ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.fivehundredpx.views import ( FiveHundredPxOAuthAdapter, ) from allauth.socialaccount.providers.oauth.provider import OAuthProvider class FiveHundredPxAccount(ProviderAccount): def get_profile_url(self): return "https://500px.com/%s" % self.account.extra_data.get("username") def get_avatar_url(self): return self.account.extra_data.get("userpic_url") class FiveHundredPxProvider(OAuthProvider): id = "500px" name = "500px" package = "allauth.socialaccount.providers.fivehundredpx" account_class = FiveHundredPxAccount oauth_adapter_class = FiveHundredPxOAuthAdapter def get_default_scope(self): return [] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( username=data.get("username"), email=data.get("email"), first_name=data.get("firstname"), last_name=data.get("lastname"), ) provider_classes = [FiveHundredPxProvider] django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/tests.py000066400000000000000000000064321467545753200274120ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FiveHundredPxProvider class FiveHundredPxTests(OAuthTestsMixin, TestCase): provider_id = FiveHundredPxProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """{ "user": { "id": 5751454, "username": "testuser", "firstname": "Test", "lastname": "User", "birthday": null, "sex": 0, "city": "San Francisco", "state": "California", "country": "United States", "registration_date": "2015-12-12T03:20:31-05:00", "about": "About me.", "usertype": 0, "fotomoto_on": true, "locale": "en", "show_nude": false, "allow_sale_requests": 1, "fullname": "Test User", "userpic_url": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/1.jpg?1", "userpic_https_url": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/1.jpg?1", "cover_url": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/cover_2048.jpg?7", "upgrade_status": 2, "store_on": true, "photos_count": 68, "galleries_count": 2, "affection": 1888, "in_favorites_count": 340, "friends_count": 181, "followers_count": 150, "analytics_code": null, "invite_pending": false, "invite_accepted": false, "email": "test@example.com", "shadow_email": "test@example.com", "upload_limit": null, "upload_limit_expiry": "2016-12-01T13:33:55-05:00", "upgrade_type": 2, "upgrade_status_expiry": "2017-05-27", "auth": { "facebook": 0, "twitter": 0, "google_oauth2": 0 }, "presubmit_for_licensing": null, "avatars": { "default": { "http": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/1.jpg?1", "https": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/1.jpg?1" }, "large": { "http": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/2.jpg?1", "https": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/2.jpg?1" }, "small": { "http": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/1.jpg?1", "https": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/1.jpg?1" }, "tiny": { "http": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/4.jpg?1", "https": "https://pacdn.500px.org/10599609/8e20991262c468a866918dcbe2f7e9a30e2c2c9c/4.jpg?1" } } } }""", ) ] # noqa def get_expected_to_str(self): return "testuser" django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/urls.py000066400000000000000000000002631467545753200272310ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import FiveHundredPxProvider urlpatterns = default_urlpatterns(FiveHundredPxProvider) django-allauth-65.0.2/allauth/socialaccount/providers/fivehundredpx/views.py000066400000000000000000000021441467545753200274010ustar00rootroot00000000000000import json from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) API_BASE = "https://api.500px.com/v1" class FiveHundredPxAPI(OAuth): """ Verifying 500px credentials """ url = API_BASE + "/users" def get_user_info(self): return json.loads(self.query(self.url))["user"] class FiveHundredPxOAuthAdapter(OAuthAdapter): provider_id = "500px" request_token_url = API_BASE + "/oauth/request_token" access_token_url = API_BASE + "/oauth/access_token" authorize_url = API_BASE + "/oauth/authorize" def complete_login(self, request, app, token, response): client = FiveHundredPxAPI( request, app.client_id, app.secret, self.request_token_url ) extra_data = client.get_user_info() return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(FiveHundredPxOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(FiveHundredPxOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/flickr/000077500000000000000000000000001467545753200242705ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/flickr/__init__.py000066400000000000000000000000001467545753200263670ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/flickr/provider.py000066400000000000000000000040351467545753200264760ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.flickr.views import FlickrOAuthAdapter from allauth.socialaccount.providers.oauth.provider import OAuthProvider class FlickrAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("person").get("profileurl").get("_content") def get_avatar_url(self): return self.account.extra_data.get("picture-url") def to_str(self): username = ( self.account.extra_data.get("person", {}) .get("username", {}) .get("_content") ) if username: return username realname = ( self.account.extra_data.get("person", {}) .get("realname", {}) .get("_content") ) if realname: return realname return super().to_str() class FlickrProvider(OAuthProvider): id = "flickr" name = "Flickr" account_class = FlickrAccount oauth_adapter_class = FlickrOAuthAdapter def get_default_scope(self): scope = [] return scope def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if "perms" not in ret: ret["perms"] = "read" return ret def get_profile_fields(self): default_fields = [ "id", "first-name", "last-name", "email-address", "picture-url", "public-profile-url", ] fields = self.get_settings().get("PROFILE_FIELDS", default_fields) return fields def extract_uid(self, data): return data["person"]["nsid"] def extract_common_fields(self, data): person = data.get("person", {}) name = person.get("realname", {}).get("_content") username = person.get("username", {}).get("_content") return dict(email=data.get("email-address"), name=name, username=username) provider_classes = [FlickrProvider] django-allauth-65.0.2/allauth/socialaccount/providers/flickr/tests.py000066400000000000000000000072161467545753200260120ustar00rootroot00000000000000from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FlickrProvider class FlickrTests(OAuthTestsMixin, TestCase): provider_id = FlickrProvider.id def get_mocked_response(self): # return [ MockedResponse( 200, r""" {"stat": "ok", "user": { "username": { "_content": "pennersr"}, "id": "12345678@N00"}} """, ), # noqa MockedResponse( 200, r""" {"person": {"username": {"_content": "pennersr"}, "photosurl": {"_content": "http://www.flickr.com/photos/12345678@N00/"}, "nsid": "12345678@N00", "path_alias": null, "photos": {"count": {"_content": 0}, "firstdatetaken": {"_content": null}, "views": {"_content": "28"}, "firstdate": {"_content": null}}, "iconserver": "0", "description": {"_content": ""}, "mobileurl": {"_content": "http://m.flickr.com/photostream.gne?id=6294613"}, "profileurl": { "_content": "http://www.flickr.com/people/12345678@N00/"}, "mbox_sha1sum": {"_content": "5e5b359c123e54f95236209c8808d607a5cdd21e"}, "ispro": 0, "location": {"_content": ""}, "id": "12345678@N00", "realname": {"_content": "raymond penners"}, "iconfarm": 0}, "stat": "ok"} """, ), ] # noqa def get_expected_to_str(self): return "pennersr" def test_login(self): super().test_login() account = SocialAccount.objects.get(uid="12345678@N00") f_account = account.get_provider_account() self.assertEqual(account.user.first_name, "raymond") self.assertEqual(account.user.last_name, "penners") self.assertEqual( f_account.get_profile_url(), "http://www.flickr.com/people/12345678@N00/", ) self.assertEqual(f_account.to_str(), "pennersr") class FlickrWithoutRealNameTests(OAuthTestsMixin, TestCase): """Separate test for Flickr accounts without real names""" provider_id = FlickrProvider.id def get_mocked_response(self): # return [ MockedResponse( 200, r""" {"stat": "ok", "user": { "username": { "_content": "pennersr"}, "id": "12345678@N00"}} """, ), # noqa MockedResponse( 200, r""" {"person": {"username": {"_content": "pennersr"}, "photosurl": {"_content": "http://www.flickr.com/photos/12345678@N00/"}, "nsid": "12345678@N00", "path_alias": null, "photos": {"count": {"_content": 0}, "firstdatetaken": {"_content": null}, "views": {"_content": "28"}, "firstdate": {"_content": null}}, "iconserver": "0", "description": {"_content": ""}, "mobileurl": {"_content": "http://m.flickr.com/photostream.gne?id=6294613"}, "profileurl": { "_content": "http://www.flickr.com/people/12345678@N00/"}, "mbox_sha1sum": {"_content": "5e5b359c123e54f95236209c8808d607a5cdd21e"}, "ispro": 0, "location": {"_content": ""}, "id": "12345678@N00", "realname": {"_content": ""}, "iconfarm": 0}, "stat": "ok"} """, ), ] # noqa def get_expected_to_str(self): return "pennersr" def test_login(self): super().test_login() account = SocialAccount.objects.get(uid="12345678@N00") f_account = account.get_provider_account() self.assertEqual(account.user.first_name, "") self.assertEqual(account.user.last_name, "") self.assertEqual( f_account.get_profile_url(), "http://www.flickr.com/people/12345678@N00/", ) self.assertEqual(f_account.to_str(), "pennersr") django-allauth-65.0.2/allauth/socialaccount/providers/flickr/urls.py000066400000000000000000000002451467545753200256300ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import FlickrProvider urlpatterns = default_urlpatterns(FlickrProvider) django-allauth-65.0.2/allauth/socialaccount/providers/flickr/views.py000066400000000000000000000027061467545753200260040ustar00rootroot00000000000000import json from django.utils.http import urlencode from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class FlickrAPI(OAuth): api_url = "https://api.flickr.com/services/rest" def get_user_info(self): default_params = {"nojsoncallback": "1", "format": "json"} p = dict({"method": "flickr.test.login"}, **default_params) u = json.loads(self.query(self.api_url + "?" + urlencode(p))) p = dict( {"method": "flickr.people.getInfo", "user_id": u["user"]["id"]}, **default_params, ) user = json.loads(self.query(self.api_url + "?" + urlencode(p))) return user class FlickrOAuthAdapter(OAuthAdapter): provider_id = "flickr" request_token_url = "http://www.flickr.com/services/oauth/request_token" access_token_url = "http://www.flickr.com/services/oauth/access_token" authorize_url = "http://www.flickr.com/services/oauth/authorize" def complete_login(self, request, app, token, response): client = FlickrAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info() return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(FlickrOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(FlickrOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/foursquare/000077500000000000000000000000001467545753200252125ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/foursquare/__init__.py000066400000000000000000000000001467545753200273110ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/foursquare/provider.py000066400000000000000000000021251467545753200274160ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.foursquare.views import ( FoursquareOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class FoursquareAccount(ProviderAccount): def get_profile_url(self): return "https://foursquare.com/user/" + self.account.extra_data.get("id") def get_avatar_url(self): return self.account.extra_data.get("photo") def to_str(self): dflt = super().to_str() return self.account.extra_data.get("contact", {}).get("email", dflt) class FoursquareProvider(OAuth2Provider): id = "foursquare" name = "Foursquare" account_class = FoursquareAccount oauth2_adapter_class = FoursquareOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( first_name=data.get("firstname"), last_name=data.get("lastname"), email=data.get("contact").get("email"), ) provider_classes = [FoursquareProvider] django-allauth-65.0.2/allauth/socialaccount/providers/foursquare/tests.py000066400000000000000000000050621467545753200267310ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FoursquareProvider class FoursquareTests(OAuth2TestsMixin, TestCase): provider_id = FoursquareProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"notifications": [{"item": {"unreadCount": 0}, "type": "notificationTray"}], "meta": {"code": 200}, "response": { "user": { "photo": { "prefix": "https://irs0.4sqi.net/img/user/", "suffix": "/blank_boy.png"}, "pings": false, "homeCity": "Athens, ESYE31", "id": "76077726", "badges": {"count": 0, "items": []}, "referralId": "u-76077726", "friends": { "count": 0, "groups": [{"count": 0, "items": [], "type": "friends", "name": "Mutual friends"}, {"count": 0, "items": [], "type": "others", "name": "Other friends"}] }, "createdAt": 1389624445, "tips": {"count": 0}, "type": "user", "bio": "", "relationship": "self", "lists": { "count": 1, "groups": [{"count": 1, "items": [{"description": "", "collaborative": false, "url": "/user/76077726/list/todos", "editable": false, "listItems": {"count": 0}, "id": "76077726/todos", "followers": {"count": 0}, "user": {"gender": "male", "firstName": "\u03a1\u03c9\u03bc\u03b1\u03bd\u03cc\u03c2", "relationship": "self", "photo": {"prefix": "https://irs0.4sqi.net/img/user/", "suffix": "/blank_boy.png"}, "lastName": "\u03a4\u03c3\u03bf\u03c5\u03c1\u03bf\u03c0\u03bb\u03ae\u03c2", "id": "76077726"}, "public": false, "canonicalUrl": "https://foursquare.com/user/76077726/list/todos", "name": "My to-do list"}], "type": "created"}, {"count": 0, "items": [], "type": "followed"}] }, "photos": {"count": 0, "items": []}, "checkinPings": "off", "scores": {"max": 0, "checkinsCount": 0, "goal": 50, "recent": 0}, "checkins": {"count": 0, "items": []}, "firstName": "\u03a1\u03c9\u03bc\u03b1\u03bd\u03cc\u03c2", "gender": "male", "contact": {"email": "romdimtsouroplis@example.com"}, "lastName": "\u03a4\u03c3\u03bf\u03c5\u03c1\u03bf\u03c0\u03bb\u03ae\u03c2", "following": {"count": 0, "groups": [{"count": 0, "items": [], "type": "following", "name": "Mutual following"}, {"count": 0, "items": [], "type": "others", "name": "Other following"}]}, "requests": {"count": 0}, "mayorships": {"count": 0, "items": []}} } } """, ) def get_expected_to_str(self): return "romdimtsouroplis@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/foursquare/urls.py000066400000000000000000000002561467545753200265540ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import FoursquareProvider urlpatterns = default_urlpatterns(FoursquareProvider) django-allauth-65.0.2/allauth/socialaccount/providers/foursquare/views.py000066400000000000000000000024331467545753200267230ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class FoursquareOAuth2Adapter(OAuth2Adapter): provider_id = "foursquare" access_token_url = "https://foursquare.com/oauth2/access_token" # Issue ?? -- this one authenticates over and over again... # authorize_url = 'https://foursquare.com/oauth2/authorize' authorize_url = "https://foursquare.com/oauth2/authenticate" profile_url = "https://api.foursquare.com/v2/users/self" def complete_login(self, request, app, token, **kwargs): # Foursquare needs a version number for their API requests as # documented here # https://developer.foursquare.com/overview/versioning resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"oauth_token": token.token, "v": "20140116"}, ) ) extra_data = resp.json()["response"]["user"] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(FoursquareOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FoursquareOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/frontier/000077500000000000000000000000001467545753200246465ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/frontier/__init__.py000066400000000000000000000000001467545753200267450ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/frontier/provider.py000066400000000000000000000027511467545753200270570ustar00rootroot00000000000000import hashlib from urllib.parse import urlencode from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.frontier.views import ( FrontierOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class FrontierAccount(ProviderAccount): def get_profile_url(self): return None def get_avatar_url(self): return "https://www.gravatar.com/avatar/%s?%s" % ( hashlib.md5( self.account.extra_data.get("email").lower().encode("utf-8") ).hexdigest(), urlencode({"d": "mp"}), ) class FrontierProvider(OAuth2Provider): id = "frontier" name = "Frontier" account_class = FrontierAccount oauth2_adapter_class = FrontierOAuth2Adapter def get_default_scope(self): scope = ["auth", "capi"] return scope def extract_uid(self, data): return str(data["customer_id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("email"), last_name=data.get("lastname"), first_name=data.get("firstname"), ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [FrontierProvider] django-allauth-65.0.2/allauth/socialaccount/providers/frontier/tests.py000066400000000000000000000044241467545753200263660ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FrontierProvider class FrontierTests(OAuth2TestsMixin, TestCase): provider_id = FrontierProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "email": "johndoe@example.com", "customer_id": "1234567", "firstname": "John", "developer": false, "lastname": "Doe", "allowedDownloads": ["FORC-FDEV-D-1010", "FORC-FDEV-D-1012", "COMBAT_TUTORIAL_DEMO", "FORC-FDEV-D-1013", "PUBLIC_TEST_SERVER", "FORC_FDEV_V_ADDER_LRPO", "FORC_FDEV_V_CHALLENGER_LRPO", "FORC_FDEV_V_CHIEFTAIN_LRPO", "FORC_FDEV_V_CRUSADER_LRPO", "FORC_FDEV_V_ANACONDA_LRPO", "FORC_FDEV_V_ASP_LRPO", "FORC_FDEV_V_ASP_SCOUT_LRPO", "FORC_FDEV_V_BELUGA_LRPO", "FORC_FDEV_V_COBRA_MKIII_LRPO", "FORC_FDEV_V_DIAMOND_EXPLORER_LRPO", "FORC_FDEV_V_COBRA_MKIV_LRPO", "FORC_FDEV_V_DIAMOND_SCOUT_LRPO", "FORC_FDEV_V_DOLPHIN_LRPO", "FORC_FDEV_V_EAGLE_LRPO", "FORC_FDEV_V_FEDERAL_ASSAULT_LRPO", "FORC_FDEV_V_FEDERAL_CORVETTE_LRPO", "FORC_FDEV_V_FEDDROP_LRPO", "FORC_FDEV_V_FEDERAL_FIGHTER_LRPO", "FORC_FDEV_V_FEDERAL_GUNSHIP_LRPO", "FORC_FDEV_V_FERDELANCE_LRPO", "FORC_FDEV_V_HAULER_LRPO", "FORC_FDEV_V_CLIPPER_LRPO", "FORC_FDEV_V_IMPERIAL_COURIER_LRPO", "FORC_FDEV_V_IMPERIAL_CUTTER_LRPO", "FORC_FDEV_V_IMPERIAL_EAGLE_LRPO", "FORC_FDEV_V_IMPERIAL_FIGHTER_LRPO", "FORC_FDEV_V_KEELBACK_LRPO", "FORC_FDEV_V_KRAIT_LRPO", "FORC_FDEV_V_KRAIT_LITE_LRPO", "FORC_FDEV_V_MAMBA_LRPO", "FORC_FDEV_V_ORCA_LRPO", "FORC_FDEV_V_PYTHON_LRPO", "FORC_FDEV_V_SIDEWINDER_LRPO", "FORC_FDEV_V_TAIPAN_LRPO", "FORC_FDEV_V_MAMMOTH_LRPO", "FORC_FDEV_V_TYPE6_LRPO", "FORC_FDEV_V_TYPE7_LRPO", "FORC_FDEV_V_TYPE9_LRPO", "FORC_FDEV_V_VIPER_MKIII_LRPO", "FORC_FDEV_V_VIPER_MKIV_LRPO", "FORC_FDEV_V_VULTURE_LRPO", "FORC-FDEV-D-1022", "FORC_FDEV_V_DECAL_1091", "FORC_FDEV_V_DECAL_1100", "FORC_FDEV_V_DECAL_1149", "FORC_FDEV_V_DECAL_1150", "FORC_FDEV_V_DECAL_1151", "FORC_FDEV_V_DECAL_1176", "FORC_FDEV_V_DECAL_1177", "FORC-FDEV-DO-1000", "FORC-FDEV-DO-1003", "FORC-FDEV-DO-1006", "PUBLIC_TEST_SERVER_OD"], "platform": "frontier" }""", ) def get_expected_to_str(self): return "johndoe@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/frontier/urls.py000066400000000000000000000002521467545753200262040ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import FrontierProvider urlpatterns = default_urlpatterns(FrontierProvider) django-allauth-65.0.2/allauth/socialaccount/providers/frontier/views.py000066400000000000000000000017411467545753200263600ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class FrontierOAuth2Adapter(OAuth2Adapter): provider_id = "frontier" AUTH_API = "https://auth.frontierstore.net" access_token_url = AUTH_API + "/token" authorize_url = AUTH_API + "/auth" profile_url = AUTH_API + "/me" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer " + token.token}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(FrontierOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FrontierOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/fxa/000077500000000000000000000000001467545753200235745ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/fxa/__init__.py000066400000000000000000000000001467545753200256730ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/fxa/constants.py000066400000000000000000000005351467545753200261650ustar00rootroot00000000000000from django.conf import settings _FXA_SETTINGS = getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}).get("fxa", {}) FXA_OAUTH_ENDPOINT = _FXA_SETTINGS.get( "OAUTH_ENDPOINT", "https://oauth.accounts.firefox.com/v1" ) FXA_PROFILE_ENDPOINT = _FXA_SETTINGS.get( "PROFILE_ENDPOINT", "https://profile.accounts.firefox.com/v1" ) PROVIDER_ID = "fxa" django-allauth-65.0.2/allauth/socialaccount/providers/fxa/models.py000066400000000000000000000000001467545753200254170ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/fxa/provider.py000066400000000000000000000014661467545753200260070ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.fxa.constants import PROVIDER_ID from allauth.socialaccount.providers.fxa.views import ( FirefoxAccountsOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class FirefoxAccountsAccount(ProviderAccount): pass class FirefoxAccountsProvider(OAuth2Provider): id = PROVIDER_ID name = "Firefox Accounts" account_class = FirefoxAccountsAccount oauth2_adapter_class = FirefoxAccountsOAuth2Adapter def get_default_scope(self): return ["profile"] def extract_uid(self, data): return str(data["uid"]) def extract_common_fields(self, data): return dict(email=data.get("email")) provider_classes = [FirefoxAccountsProvider] django-allauth-65.0.2/allauth/socialaccount/providers/fxa/tests.py000066400000000000000000000010531467545753200253070ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import FirefoxAccountsProvider class FirefoxAccountsTests(OAuth2TestsMixin, TestCase): provider_id = FirefoxAccountsProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "uid":"6d940dd41e636cc156074109b8092f96", "email":"user@example.com" }""", ) def get_expected_to_str(self): return "user@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/fxa/urls.py000066400000000000000000000002701467545753200251320ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import FirefoxAccountsProvider urlpatterns = default_urlpatterns(FirefoxAccountsProvider) django-allauth-65.0.2/allauth/socialaccount/providers/fxa/views.py000066400000000000000000000017751467545753200253150ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .constants import FXA_OAUTH_ENDPOINT, FXA_PROFILE_ENDPOINT, PROVIDER_ID class FirefoxAccountsOAuth2Adapter(OAuth2Adapter): provider_id = PROVIDER_ID access_token_url = FXA_OAUTH_ENDPOINT + "/token" authorize_url = FXA_OAUTH_ENDPOINT + "/authorization" profile_url = FXA_PROFILE_ENDPOINT + "/profile" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(FirefoxAccountsOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(FirefoxAccountsOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/gitea/000077500000000000000000000000001467545753200241075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/gitea/__init__.py000066400000000000000000000000001467545753200262060ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/gitea/provider.py000066400000000000000000000024061467545753200263150ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.gitea.views import GiteaOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class GiteaAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("html_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") def to_str(self): dflt = super(GiteaAccount, self).to_str() return next( value for value in ( self.account.extra_data.get("username", None), self.account.extra_data.get("login", None), dflt, ) if value is not None ) class GiteaProvider(OAuth2Provider): id = "gitea" name = "Gitea" account_class = GiteaAccount oauth2_adapter_class = GiteaOAuth2Adapter def get_default_scope(self): scope = [] return scope def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("login"), name=data.get("name"), ) provider_classes = [GiteaProvider] django-allauth-65.0.2/allauth/socialaccount/providers/gitea/tests.py000066400000000000000000000035001467545753200256210ustar00rootroot00000000000000from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import GiteaProvider class GiteaTests(OAuth2TestsMixin, TestCase): provider_id = GiteaProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "id": 4940, "login": "giteauser", "full_name": "", "email": "giteauser@example.com", "avatar_url": "https://gitea.com/user/avatar/giteauser/-1", "language": "en-US", "is_admin": true, "last_login": "2021-08-20T20:07:39Z", "created": "2018-05-03T16:04:34Z", "restricted": false, "active": true, "prohibit_login": false, "location": "", "website": "", "description": "", "visibility": "public", "followers_count": 0, "following_count": 0, "starred_repos_count": 0, "username": "giteauser" }""", ) def get_expected_to_str(self): return "giteauser" def test_account_name_null(self): """String conversion when Gitea responds with empty username""" data = """{ "id": 4940, "login": "giteauser", "username": null }""" self.login(MockedResponse(200, data)) socialaccount = SocialAccount.objects.get(uid="4940") self.assertIsNone(socialaccount.extra_data.get("name")) account = socialaccount.get_provider_account() self.assertIsNotNone(account.to_str()) self.assertEqual(account.to_str(), "giteauser") django-allauth-65.0.2/allauth/socialaccount/providers/gitea/urls.py000066400000000000000000000002441467545753200254460ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import GiteaProvider urlpatterns = default_urlpatterns(GiteaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/gitea/views.py000066400000000000000000000023321467545753200256160ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class GiteaOAuth2Adapter(OAuth2Adapter): provider_id = "gitea" settings = app_settings.PROVIDERS.get(provider_id, {}) if "GITEA_URL" in settings: web_url = settings.get("GITEA_URL").rstrip("/") else: web_url = "https://gitea.com" api_url = "{0}/api/v1".format(web_url) access_token_url = "{0}/login/oauth/access_token".format(web_url) authorize_url = "{0}/login/oauth/authorize".format(web_url) profile_url = "{0}/user".format(api_url) def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "token {}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(GiteaOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(GiteaOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/github/000077500000000000000000000000001467545753200243005ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/github/__init__.py000066400000000000000000000000001467545753200263770ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/github/provider.py000066400000000000000000000031311467545753200265020ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.github.views import GitHubOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class GitHubAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("html_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") class GitHubProvider(OAuth2Provider): id = "github" name = "GitHub" account_class = GitHubAccount oauth2_adapter_class = GitHubOAuth2Adapter def get_default_scope(self): scope = [] if app_settings.QUERY_EMAIL: scope.append("user:email") return scope def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("login"), name=data.get("name"), ) def extract_extra_data(self, data): if "emails" in data: data = dict(data) data.pop("emails") return data def extract_email_addresses(self, data): ret = [] for email in data.get("emails", []): ret.append( EmailAddress( email=email["email"], primary=email["primary"], verified=email["verified"], ) ) return ret provider_classes = [GitHubProvider] django-allauth-65.0.2/allauth/socialaccount/providers/github/tests.py000066400000000000000000000102301467545753200260100ustar00rootroot00000000000000from unittest.mock import patch from allauth.account.models import EmailAddress from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import GitHubProvider class GitHubTests(OAuth2TestsMixin, TestCase): provider_id = GitHubProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """ { "type":"User", "organizations_url":"https://api.github.com/users/pennersr/orgs", "gists_url":"https://api.github.com/users/pennersr/gists{/gist_id}", "received_events_url":"https://api.github.com/users/pennersr/received_events", "gravatar_id":"8639768262b8484f6a3380f8db2efa5b", "followers":16, "blog":"http://www.intenct.info", "avatar_url":"https://secure.gravatar.com/avatar/8639768262b8484f6a3380f8db2efa5b?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png", "login":"pennersr", "created_at":"2010-02-10T12:50:51Z", "company":"IntenCT", "subscriptions_url":"https://api.github.com/users/pennersr/subscriptions", "public_repos":14, "hireable":false, "url":"https://api.github.com/users/pennersr", "public_gists":0, "starred_url":"https://api.github.com/users/pennersr/starred{/owner}{/repo}", "html_url":"https://github.com/pennersr", "location":"The Netherlands", "bio":null, "name":"Raymond Penners", "repos_url":"https://api.github.com/users/pennersr/repos", "followers_url":"https://api.github.com/users/pennersr/followers", "id":201022, "following":0, "email":"raymond.penners@intenct.nl", "events_url":"https://api.github.com/users/pennersr/events{/privacy}", "following_url":"https://api.github.com/users/pennersr/following" }""", ), MockedResponse( 200, """ [{ "email": "octocat@github.com", "verified": true, "primary": true, "visibility": "public" }] """, ), ] def get_expected_to_str(self): return "pennersr" def test_account_name_null(self): """String conversion when GitHub responds with empty name""" mocks = [ MockedResponse( 200, """ { "type": "User", "id": 201022, "login": "pennersr", "name": null } """, ), MockedResponse( 200, """ [ { "email": "octocat@github.com", "verified": true, "primary": true, "visibility": "public" }, { "email": "secONDary@GitHub.COM", "verified": true, "primary": false, "visibility": "public" } ] """, ), ] with patch( "allauth.socialaccount.adapter.DefaultSocialAccountAdapter.populate_user" ) as populate_mock: self.login(mocks) populate_data = populate_mock.call_args[0][2] assert populate_data["email"] == "octocat@github.com" socialaccount = SocialAccount.objects.get(uid="201022") self.assertIsNone(socialaccount.extra_data.get("name")) account = socialaccount.get_provider_account() self.assertIsNotNone(account.to_str()) self.assertEqual(account.to_str(), "pennersr") self.assertEqual(socialaccount.user.email, "octocat@github.com") self.assertTrue( EmailAddress.objects.filter( primary=False, verified=True, email="secondary@github.com", user=socialaccount.user, ).exists() ) self.assertTrue("emails" not in socialaccount.extra_data) django-allauth-65.0.2/allauth/socialaccount/providers/github/urls.py000066400000000000000000000002461467545753200256410ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import GitHubProvider urlpatterns = default_urlpatterns(GitHubProvider) django-allauth-65.0.2/allauth/socialaccount/providers/github/views.py000066400000000000000000000035211467545753200260100ustar00rootroot00000000000000from typing import Optional from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class GitHubOAuth2Adapter(OAuth2Adapter): provider_id = "github" settings = app_settings.PROVIDERS.get(provider_id, {}) if "GITHUB_URL" in settings: web_url = settings.get("GITHUB_URL").rstrip("/") api_url = "{0}/api/v3".format(web_url) else: web_url = "https://github.com" api_url = "https://api.github.com" access_token_url = "{0}/login/oauth/access_token".format(web_url) authorize_url = "{0}/login/oauth/authorize".format(web_url) profile_url = "{0}/user".format(api_url) emails_url = "{0}/user/emails".format(api_url) def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "token {}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() if app_settings.QUERY_EMAIL: if emails := self.get_emails(headers): extra_data["emails"] = emails return self.get_provider().sociallogin_from_response(request, extra_data) def get_emails(self, headers) -> Optional[list]: resp = ( get_adapter().get_requests_session().get(self.emails_url, headers=headers) ) # https://api.github.com/user/emails -- 404 is documented to occur. if resp.status_code == 404: return None resp.raise_for_status() return resp.json() oauth2_login = OAuth2LoginView.adapter_view(GitHubOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(GitHubOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/gitlab/000077500000000000000000000000001467545753200242605ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/gitlab/__init__.py000066400000000000000000000000001467545753200263570ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/gitlab/provider.py000066400000000000000000000016611467545753200264700ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.gitlab.views import GitLabOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class GitLabAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("web_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") class GitLabProvider(OAuth2Provider): id = "gitlab" name = "GitLab" account_class = GitLabAccount oauth2_adapter_class = GitLabOAuth2Adapter def get_default_scope(self): return ["read_user"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), name=data.get("name"), ) provider_classes = [GitLabProvider] django-allauth-65.0.2/allauth/socialaccount/providers/gitlab/tests.py000066400000000000000000000072431467545753200260020ustar00rootroot00000000000000import json from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.gitlab.provider import GitLabProvider from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .views import _check_errors class GitLabTests(OAuth2TestsMixin, TestCase): provider_id = GitLabProvider.id _uid = 2 def get_mocked_response(self): return MockedResponse( 200, """ { "avatar_url": "https://secure.gravatar.com/avatar/123", "bio": null, "can_create_group": true, "can_create_project": true, "color_scheme_id": 5, "confirmed_at": "2015-03-02T16:53:58.370Z", "created_at": "2015-03-02T16:53:58.885Z", "current_sign_in_at": "2018-06-12T18:44:49.985Z", "email": "mr.bob@gitlab.example.com", "external": false, "id": 2, "identities": [], "last_activity_on": "2018-06-11", "last_sign_in_at": "2018-05-31T14:59:44.527Z", "linkedin": "", "location": null, "name": "Mr Bob", "organization": null, "projects_limit": 10, "shared_runners_minutes_limit": 2000, "skype": "", "state": "active", "theme_id": 6, "twitter": "mrbob", "two_factor_enabled": true, "username": "mr.bob", "web_url": "https://gitlab.example.com/u/mr.bob", "website_url": "" } """, ) def get_expected_to_str(self): return "mr.bob" def test_valid_response(self): data = {"id": 12345} response = MockedResponse(200, json.dumps(data)) self.assertEqual(_check_errors(response), data) def test_invalid_data(self): response = MockedResponse(200, json.dumps({})) with self.assertRaises(OAuth2Error): # No id, raises _check_errors(response) def test_account_invalid_response(self): body = ( "403 Forbidden - You (@domain.com) must accept the Terms of " "Service in order to perform this action. Please access GitLab " "from a web browser to accept these terms." ) response = MockedResponse(403, body) # GitLab allow users to login with their API and provides # an error requiring the user to accept the Terms of Service. # see: https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45849 with self.assertRaises(OAuth2Error): # no id, 4xx code, raises _check_errors(response) def test_error_response(self): body = "403 Forbidden" response = MockedResponse(403, body) with self.assertRaises(OAuth2Error): # no id, 4xx code, raises _check_errors(response) def test_invalid_response(self): response = MockedResponse(200, json.dumps({})) with self.assertRaises(OAuth2Error): # No id, raises _check_errors(response) def test_bad_response(self): response = MockedResponse(400, json.dumps({})) with self.assertRaises(OAuth2Error): # bad json, raises _check_errors(response) def test_extra_data(self): self.login(self.get_mocked_response()) account = SocialAccount.objects.get(uid=str(self._uid)) self.assertEqual(account.extra_data["id"], self._uid) django-allauth-65.0.2/allauth/socialaccount/providers/gitlab/urls.py000066400000000000000000000003131467545753200256140ustar00rootroot00000000000000from allauth.socialaccount.providers.gitlab.provider import GitLabProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(GitLabProvider) django-allauth-65.0.2/allauth/socialaccount/providers/gitlab/views.py000066400000000000000000000053721467545753200257760ustar00rootroot00000000000000from allauth.core import context from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) def _check_errors(response): # 403 error's are presented as user-facing errors if response.status_code == 403: msg = response.content raise OAuth2Error("Invalid data from GitLab API: %r" % (msg)) try: data = response.json() except ValueError: # JSONDecodeError on py3 raise OAuth2Error("Invalid JSON from GitLab API: %r" % (response.text)) if response.status_code >= 400 or "error" in data: # For errors, we expect the following format: # {"error": "error_name", "error_description": "Oops!"} # For example, if the token is not valid, we will get: # {"message": "status_code - message"} error = data.get("error", "") or response.status_code desc = data.get("error_description", "") or data.get("message", "") raise OAuth2Error("GitLab error: %s (%s)" % (error, desc)) # The expected output from the API follows this format: # {"id": 12345, ...} if "id" not in data: # If the id is not present, the output is not usable (no UID) raise OAuth2Error("Invalid data from GitLab API: %r" % (data)) return data class GitLabOAuth2Adapter(OAuth2Adapter): provider_id = "gitlab" provider_default_url = "https://gitlab.com" provider_api_version = "v4" def _build_url(self, path): settings = app_settings.PROVIDERS.get(self.provider_id, {}) gitlab_url = settings.get("GITLAB_URL", self.provider_default_url) # Prefer app based setting. app = get_adapter().get_app(context.request, provider=self.provider_id) gitlab_url = app.settings.get("gitlab_url", gitlab_url) return f"{gitlab_url}{path}" @property def access_token_url(self): return self._build_url("/oauth/token") @property def authorize_url(self): return self._build_url("/oauth/authorize") @property def profile_url(self): return self._build_url(f"/api/{self.provider_api_version}/user") def complete_login(self, request, app, token, response): response = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) data = _check_errors(response) return self.get_provider().sociallogin_from_response(request, data) oauth2_login = OAuth2LoginView.adapter_view(GitLabOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(GitLabOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/globus/000077500000000000000000000000001467545753200243115ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/globus/__init__.py000066400000000000000000000000001467545753200264100ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/globus/provider.py000066400000000000000000000023601467545753200265160ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ( ProviderAccount, ProviderException, ) from allauth.socialaccount.providers.globus.views import GlobusOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class GlobusAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("web_url", "dflt") def get_avatar_url(self): return self.account.extra_data.get("avatar_url", "dflt") class GlobusProvider(OAuth2Provider): id = "globus" name = "Globus" account_class = GlobusAccount oauth2_adapter_class = GlobusOAuth2Adapter def extract_uid(self, data): if "sub" not in data: raise ProviderException("Globus OAuth error", data) return str(data["sub"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("preferred_username"), name=data.get("name"), ) def get_default_scope(self): scope = ["openid", "profile", "offline_access"] if app_settings.QUERY_EMAIL: scope.append("email") return scope provider_classes = [GlobusProvider] django-allauth-65.0.2/allauth/socialaccount/providers/globus/tests.py000066400000000000000000000016451467545753200260330ustar00rootroot00000000000000from django.test.utils import override_settings from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import GlobusProvider class GlobusTests(OAuth2TestsMixin, TestCase): provider_id = GlobusProvider.id @override_settings(SOCIALACCOUNT_QUERY_EMAIL=True) def get_mocked_response(self): return MockedResponse( 200, """ { "identity_provider_display_name": "University of Gozorpazorp", "sub": "a6fc81e-4a6c1-97ac-b4c6-84ff6a8ce662", "preferred_username": "morty@ugz.edu", "identity_provider": "9a4c8312f-9432-9a7c-1654-6a987c6531fa", "organization": "University of Gozorpazorp", "email": "morty@ugz.edu", "name": "Morty Smith" } """, ) def get_expected_to_str(self): return "morty@ugz.edu" django-allauth-65.0.2/allauth/socialaccount/providers/globus/urls.py000066400000000000000000000003131467545753200256450ustar00rootroot00000000000000from allauth.socialaccount.providers.globus.provider import GlobusProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(GlobusProvider) django-allauth-65.0.2/allauth/socialaccount/providers/globus/views.py000066400000000000000000000022211467545753200260150ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class GlobusOAuth2Adapter(OAuth2Adapter): provider_id = "globus" provider_default_url = "https://auth.globus.org/v2/oauth2" provider_base_url = "https://auth.globus.org/v2/oauth2" access_token_url = "{0}/token".format(provider_base_url) authorize_url = "{0}/authorize".format(provider_base_url) profile_url = "{0}/userinfo".format(provider_base_url) def complete_login(self, request, app, token, response): extra_data = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token}, headers={ "Authorization": "Bearer " + token.token, }, ) ) return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth2_login = OAuth2LoginView.adapter_view(GlobusOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(GlobusOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/google/000077500000000000000000000000001467545753200242725ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/google/__init__.py000066400000000000000000000000001467545753200263710ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/google/provider.py000066400000000000000000000067271467545753200265120ustar00rootroot00000000000000import requests from allauth.account.models import EmailAddress from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class Scope: EMAIL = "email" PROFILE = "profile" class GoogleAccount(ProviderAccount): """ The account data can be in two formats. One, originating from the /v2/userinfo endpoint: {'email': 'john.doe@gmail.com', 'given_name': 'John', 'id': '12345678901234567890', 'locale': 'en', 'name': 'John', 'picture': 'https://lh3.googleusercontent.com/a/code', 'verified_email': True} The second, which is the payload of the id_token: {'at_hash': '-someHASH', 'aud': '123-pqr.apps.googleusercontent.com', 'azp': '123-pqr.apps.googleusercontent.com', 'email': 'john.doe@gmail.com', 'email_verified': True, 'exp': 1707297277, 'given_name': 'John', 'iat': 1707293677, 'iss': 'https://accounts.google.com', 'locale': 'en', 'name': 'John', 'picture': 'https://lh3.googleusercontent.com/a/code', 'sub': '12345678901234567890'} """ def get_profile_url(self): return self.account.extra_data.get("link") def get_avatar_url(self): return self.account.extra_data.get("picture") class GoogleProvider(OAuth2Provider): id = "google" name = "Google" account_class = GoogleAccount oauth2_adapter_class = GoogleOAuth2Adapter supports_token_authentication = True def get_default_scope(self): scope = [Scope.PROFILE] if QUERY_EMAIL: scope.append(Scope.EMAIL) return scope def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["prompt"] = "select_account consent" return ret def extract_uid(self, data): if "sub" in data: return data["sub"] return data["id"] def extract_common_fields(self, data): return dict( email=data.get("email"), last_name=data.get("family_name"), first_name=data.get("given_name"), ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: verified = bool(data.get("email_verified") or data.get("verified_email")) ret.append(EmailAddress(email=email, verified=verified, primary=True)) return ret def verify_token(self, request, token): from allauth.socialaccount.providers.google import views credential = token.get("id_token") if not credential: raise get_adapter().validation_error("invalid_token") try: identity_data = views._verify_and_decode( app=self.app, credential=credential ) except (OAuth2Error, requests.RequestException) as e: raise get_adapter().validation_error("invalid_token") from e login = self.sociallogin_from_response(request, identity_data) return login provider_classes = [GoogleProvider] django-allauth-65.0.2/allauth/socialaccount/providers/google/tests.py000066400000000000000000000321471467545753200260150ustar00rootroot00000000000000import json import time from importlib import import_module from unittest.mock import Mock, patch from django.conf import settings from django.contrib.auth.models import User from django.core import mail from django.test.client import RequestFactory from django.test.utils import override_settings from django.urls import reverse import pytest from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.models import EmailAddress, EmailConfirmation from allauth.account.signals import user_signed_up from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialAccount, SocialToken from allauth.socialaccount.providers.apple.client import jwt_encode from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import TestCase, mocked_response from .provider import GoogleProvider @pytest.fixture def settings_with_google_provider(settings): settings.SOCIALACCOUNT_PROVIDERS = { "google": { "APP": { "client_id": "app123id", "key": "google", "secret": "dummy", } } } return settings @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=True, ACCOUNT_SIGNUP_FORM_CLASS=None, ACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.MANDATORY, ) class GoogleTests(OAuth2TestsMixin, TestCase): provider_id = GoogleProvider.id def setUp(self): super().setUp() self.email = "raymond.penners@example.com" self.identity_overwrites = {} def get_expected_to_str(self): return "raymond.penners@example.com" def get_google_id_token_payload(self): now = int(time.time()) client_id = "app123id" # Matches `setup_app` payload = { "iss": "https://accounts.google.com", "azp": client_id, "aud": client_id, "sub": "108204268033311374519", "hd": "example.com", "email": self.email, "email_verified": True, "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q", "name": "Raymond Penners", "picture": "https://lh5.googleusercontent.com/photo.jpg", "given_name": "Raymond", "family_name": "Penners", "locale": "en", "iat": now, "exp": now + 60 * 60, } payload.update(self.identity_overwrites) return payload def get_login_response_json(self, with_refresh_token=True): data = { "access_token": "testac", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid", "token_type": "Bearer", "id_token": jwt_encode(self.get_google_id_token_payload(), "secret"), } return json.dumps(data) @override_settings(SOCIALACCOUNT_AUTO_SIGNUP=False) def test_login(self): resp = self.login(resp_mock=None) self.assertRedirects(resp, reverse("socialaccount_signup")) def test_wrong_id_token_claim_values(self): wrong_claim_values = { "iss": "not-google", "exp": time.time() - 1, "aud": "foo", } for key, value in wrong_claim_values.items(): with self.subTest(key): self.identity_overwrites = {key: value} resp = self.login(resp_mock=None) self.assertTemplateUsed( resp, "socialaccount/authentication_error.%s" % getattr(settings, "ACCOUNT_TEMPLATE_EXTENSION", "html"), ) def test_username_based_on_email(self): self.identity_overwrites = {"given_name": "明", "family_name": "小"} self.login(resp_mock=None) user = User.objects.get(email=self.email) self.assertEqual(user.username, "raymond.penners") def test_email_verified(self): self.identity_overwrites = {"email_verified": True} self.login(resp_mock=None) email_address = EmailAddress.objects.get(email=self.email, verified=True) self.assertFalse( EmailConfirmation.objects.filter(email_address__email=self.email).exists() ) account = email_address.user.socialaccount_set.all()[0] self.assertEqual(account.extra_data["given_name"], "Raymond") def test_user_signed_up_signal(self): sent_signals = [] def on_signed_up(sender, request, user, **kwargs): sociallogin = kwargs["sociallogin"] self.assertEqual(sociallogin.account.provider, GoogleProvider.id) self.assertEqual(sociallogin.account.user, user) sent_signals.append(sender) user_signed_up.connect(on_signed_up) self.login(resp_mock=None) self.assertTrue(len(sent_signals) > 0) @override_settings(ACCOUNT_EMAIL_CONFIRMATION_HMAC=False) def test_email_unverified(self): self.identity_overwrites = {"email_verified": False} resp = self.login(resp_mock=None) email_address = EmailAddress.objects.get(email=self.email) self.assertFalse(email_address.verified) self.assertTrue( EmailConfirmation.objects.filter(email_address__email=self.email).exists() ) self.assertTemplateUsed( resp, "account/email/email_confirmation_signup_subject.txt" ) def test_email_verified_stashed(self): # http://slacy.com/blog/2012/01/how-to-set-session-variables-in-django-unit-tests/ engine = import_module(settings.SESSION_ENGINE) store = engine.SessionStore() store.save() self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key request = RequestFactory().get("/") request.session = self.client.session adapter = get_account_adapter() adapter.stash_verified_email(request, self.email) request.session.save() self.identity_overwrites = {"email_verified": False} self.login(resp_mock=None) email_address = EmailAddress.objects.get(email=self.email) self.assertTrue(email_address.verified) self.assertFalse( EmailConfirmation.objects.filter(email_address__email=self.email).exists() ) def test_account_connect(self): email = "user@example.com" user = User.objects.create(username="user", is_active=True, email=email) user.set_password("test") user.save() EmailAddress.objects.create(user=user, email=email, primary=True, verified=True) self.client.login(username=user.username, password="test") self.identity_overwrites = {"email": email, "email_verified": True} self.login(resp_mock=None, process="connect") # Check if we connected... self.assertTrue( SocialAccount.objects.filter(user=user, provider=GoogleProvider.id).exists() ) # For now, we do not pick up any new email addresses on connect self.assertEqual(EmailAddress.objects.filter(user=user).count(), 1) self.assertEqual(EmailAddress.objects.filter(user=user, email=email).count(), 1) @override_settings( ACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.MANDATORY, SOCIALACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.NONE, ) def test_social_email_verification_skipped(self): self.identity_overwrites = {"email_verified": False} self.login(resp_mock=None) email_address = EmailAddress.objects.get(email=self.email) self.assertFalse(email_address.verified) self.assertFalse( EmailConfirmation.objects.filter(email_address__email=self.email).exists() ) @override_settings( ACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.OPTIONAL, SOCIALACCOUNT_EMAIL_VERIFICATION=account_settings.EmailVerificationMethod.OPTIONAL, ) def test_social_email_verification_optional(self): self.identity_overwrites = {"email_verified": False} self.login(resp_mock=None) self.assertEqual(len(mail.outbox), 1) self.login(resp_mock=None) self.assertEqual(len(mail.outbox), 1) @override_settings( SOCIALACCOUNT_PROVIDERS={ "google": { "APP": { "client_id": "app123id", "key": "google", "secret": "dummy", } } } ) class AppInSettingsTests(GoogleTests): """ Run the same set of tests but without having a SocialApp entry. """ pass def test_login_by_token(db, client, settings_with_google_provider): client.cookies.load({"g_csrf_token": "csrf"}) with patch( "allauth.socialaccount.internal.jwtkit.jwt.get_unverified_header" ) as g_u_h: with mocked_response({"dummykid": "-----BEGIN CERTIFICATE-----"}): with patch( "allauth.socialaccount.internal.jwtkit.load_pem_x509_certificate" ) as load_pem: with patch( "allauth.socialaccount.internal.jwtkit.jwt.decode" ) as decode: decode.return_value = { "iss": "https://accounts.google.com", "aud": "client_id", "sub": "123sub", "hd": "example.com", "email": "raymond@example.com", "email_verified": True, "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q", "name": "Raymond Penners", "picture": "https://lh5.googleusercontent.com/photo.jpg", "given_name": "Raymond", "family_name": "Penners", "locale": "en", "iat": 123, "exp": 456, } g_u_h.return_value = { "alg": "RS256", "kid": "dummykid", "typ": "JWT", } pem = Mock() load_pem.return_value = pem pem.public_key.return_value = "key" resp = client.post( reverse("google_login_by_token"), {"credential": "dummy", "g_csrf_token": "csrf"}, ) assert resp.status_code == 302 socialaccount = SocialAccount.objects.get(uid="123sub") assert socialaccount.user.email == "raymond@example.com" @pytest.mark.parametrize( "id_key,verified_key", [ ("id", "email_verified"), ("sub", "verified_email"), ], ) @pytest.mark.parametrize("verified", [False, True]) def test_extract_data( id_key, verified_key, verified, settings_with_google_provider, db ): data = { "email": "a@b.com", } data[id_key] = "123" data[verified_key] = verified provider = get_adapter().get_provider(None, GoogleProvider.id) assert provider.extract_uid(data) == "123" emails = provider.extract_email_addresses(data) assert len(emails) == 1 assert emails[0].verified == verified assert emails[0].email == "a@b.com" @pytest.mark.parametrize( "fetch_userinfo,id_token_has_picture,response,expected_uid, expected_picture", [ (True, True, {"id_token": "123"}, "uid-from-id-token", "pic-from-id-token"), (True, False, {"id_token": "123"}, "uid-from-id-token", "pic-from-userinfo"), (True, True, {"access_token": "123"}, "uid-from-userinfo", "pic-from-userinfo"), ], ) @pytest.mark.parametrize("did_fetch_access_token", [False, True]) def test_complete_login_variants( response, settings_with_google_provider, db, fetch_userinfo, expected_uid, expected_picture, id_token_has_picture, did_fetch_access_token, ): with patch.object( GoogleOAuth2Adapter, "_fetch_user_info", return_value={ "id": "uid-from-userinfo", "picture": "pic-from-userinfo", }, ): id_token = {"sub": "uid-from-id-token"} if id_token_has_picture: id_token["picture"] = "pic-from-id-token" with patch( "allauth.socialaccount.providers.google.views._verify_and_decode", return_value=id_token, ) as decode_mock: request = None app = None adapter = GoogleOAuth2Adapter(request) adapter.did_fetch_access_token = did_fetch_access_token adapter.fetch_userinfo = fetch_userinfo token = SocialToken() login = adapter.complete_login(request, app, token, response) assert login.account.uid == expected_uid assert login.account.extra_data["picture"] == expected_picture if not response.get("id_token"): assert not decode_mock.called else: assert decode_mock.call_args[1]["verify_signature"] == ( not did_fetch_access_token ) django-allauth-65.0.2/allauth/socialaccount/providers/google/urls.py000066400000000000000000000006051467545753200256320ustar00rootroot00000000000000from django.urls import path from allauth.socialaccount.providers.google import views from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import GoogleProvider urlpatterns = default_urlpatterns(GoogleProvider) urlpatterns += [ path( "google/login/token/", views.login_by_token, name="google_login_by_token", ), ] django-allauth-65.0.2/allauth/socialaccount/providers/google/views.py000066400000000000000000000126211467545753200260030ustar00rootroot00000000000000import requests from django.conf import settings from django.core.exceptions import PermissionDenied, ValidationError from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.generic import View from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.internal import jwtkit from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) CERTS_URL = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("google", {}) .get("CERTS_URL", "https://www.googleapis.com/oauth2/v1/certs") ) IDENTITY_URL = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("google", {}) .get("IDENTITY_URL", "https://www.googleapis.com/oauth2/v2/userinfo") ) ACCESS_TOKEN_URL = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("google", {}) .get("ACCESS_TOKEN_URL", "https://oauth2.googleapis.com/token") ) AUTHORIZE_URL = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("google", {}) .get("AUTHORIZE_URL", "https://accounts.google.com/o/oauth2/v2/auth") ) ID_TOKEN_ISSUER = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("google", {}) .get("ID_TOKEN_ISSUER", "https://accounts.google.com") ) FETCH_USERINFO = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("google", {}) .get("FETCH_USERINFO", False) ) def _verify_and_decode(app, credential, verify_signature=True): return jwtkit.verify_and_decode( credential=credential, keys_url=CERTS_URL, issuer=ID_TOKEN_ISSUER, audience=app.client_id, lookup_kid=jwtkit.lookup_kid_pem_x509_certificate, verify_signature=verify_signature, ) class GoogleOAuth2Adapter(OAuth2Adapter): provider_id = "google" access_token_url = ACCESS_TOKEN_URL authorize_url = AUTHORIZE_URL id_token_issuer = ID_TOKEN_ISSUER identity_url = IDENTITY_URL fetch_userinfo = FETCH_USERINFO def complete_login(self, request, app, token, response, **kwargs): data = None id_token = response.get("id_token") if id_token: data = self._decode_id_token(app, id_token) if self.fetch_userinfo and "picture" not in data: info = self._fetch_user_info(token.token) picture = info.get("picture") if picture: data["picture"] = picture else: data = self._fetch_user_info(token.token) login = self.get_provider().sociallogin_from_response(request, data) return login def _decode_id_token(self, app, id_token): """ If the token was received by direct communication protected by TLS between this library and Google, we are allowed to skip checking the token signature according to the OpenID Connect Core 1.0 specification. https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation """ verify_signature = not self.did_fetch_access_token return _verify_and_decode(app, id_token, verify_signature=verify_signature) def _fetch_user_info(self, access_token): resp = ( get_adapter() .get_requests_session() .get( self.identity_url, headers={"Authorization": "Bearer {}".format(access_token)}, ) ) if not resp.ok: raise OAuth2Error("Request to user info failed") return resp.json() oauth2_login = OAuth2LoginView.adapter_view(GoogleOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(GoogleOAuth2Adapter) class LoginByTokenView(View): @method_decorator(login_not_required) def dispatch(self, request): self.adapter = get_adapter() self.provider = self.adapter.get_provider( request, GoogleOAuth2Adapter.provider_id ) try: return super().dispatch(request) except ( OAuth2Error, requests.RequestException, PermissionDenied, ValidationError, ) as exc: return render_authentication_error(request, self.provider, exception=exc) def get(self, request): # If we leave out get() it will return a response with a 405, but # we really want to show an authentication error. raise PermissionDenied("405") def post(self, request, *args, **kwargs): self.check_csrf(request) credential = request.POST.get("credential") login = self.provider.verify_token(request, {"id_token": credential}) return complete_social_login(request, login) def check_csrf(self, request): csrf_token_cookie = request.COOKIES.get("g_csrf_token") if not csrf_token_cookie: raise PermissionDenied("No CSRF token in Cookie.") csrf_token_body = request.POST.get("g_csrf_token") if not csrf_token_body: raise PermissionDenied("No CSRF token in post body.") if csrf_token_cookie != csrf_token_body: raise PermissionDenied("Failed to verify double submit cookie.") login_by_token = csrf_exempt(LoginByTokenView.as_view()) django-allauth-65.0.2/allauth/socialaccount/providers/gumroad/000077500000000000000000000000001467545753200244545ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/gumroad/__init__.py000066400000000000000000000000001467545753200265530ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/gumroad/provider.py000066400000000000000000000021271467545753200266620ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.gumroad.views import GumroadOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class GumroadAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("url") class GumroadProvider(OAuth2Provider): id = "gumroad" name = "Gumroad" account_class = GumroadAccount oauth2_adapter_class = GumroadOAuth2Adapter def get_default_scope(self): return ["edit_products"] def extract_uid(self, data): return str(data["user_id"]) def extract_common_fields(self, data): try: username = data["url"].split("https://gumroad.com/")[1] except (KeyError, IndexError, AttributeError): username = None return dict( username=username, email=data.get("email"), name=data.get("name"), twitter_handle=data.get("twitter_handle"), url=data.get("url"), ) provider_classes = [GumroadProvider] django-allauth-65.0.2/allauth/socialaccount/providers/gumroad/tests.py000066400000000000000000000015351467545753200261740ustar00rootroot00000000000000from allauth.socialaccount.providers.gumroad.provider import GumroadProvider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class GumroadTests(OAuth2TestsMixin, TestCase): provider_id = GumroadProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "success": true, "user": { "bio": "a sailor, a tailor", "name": "John Smith", "twitter_handle": null, "user_id": "G_-mnBf9b1j9A7a4ub4nFQ==", "email": "johnsmith@gumroad.com", "url": "https://gumroad.com/sailorjohn" } }""", ) def get_expected_to_str(self): return "johnsmith@gumroad.com" django-allauth-65.0.2/allauth/socialaccount/providers/gumroad/urls.py000066400000000000000000000003161467545753200260130ustar00rootroot00000000000000from allauth.socialaccount.providers.gumroad.provider import GumroadProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(GumroadProvider) django-allauth-65.0.2/allauth/socialaccount/providers/gumroad/views.py000066400000000000000000000021641467545753200261660ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class GumroadOAuth2Adapter(OAuth2Adapter): provider_id = "gumroad" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("GUMROAD_URL") access_token_url = "{0}/oauth/token".format(provider_base_url) authorize_url = "{0}/oauth/authorize".format(provider_base_url) profile_url = "https://api.gumroad.com/v2/user" def complete_login(self, request, app, token, response): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response( request, extra_data["user"] ) oauth2_login = OAuth2LoginView.adapter_view(GumroadOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(GumroadOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/hubic/000077500000000000000000000000001467545753200241105ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/hubic/__init__.py000066400000000000000000000000001467545753200262070ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/hubic/provider.py000066400000000000000000000014471467545753200263220ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.hubic.views import HubicOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class HubicAccount(ProviderAccount): pass class HubicProvider(OAuth2Provider): id = "hubic" name = "Hubic" account_class = HubicAccount oauth2_adapter_class = HubicOAuth2Adapter def extract_uid(self, data): return str(data["email"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("firstname").lower() + data.get("lastname").lower(), first_name=data.get("firstname"), last_name=data.get("lastname"), ) provider_classes = [HubicProvider] django-allauth-65.0.2/allauth/socialaccount/providers/hubic/tests.py000066400000000000000000000015051467545753200256250ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import HubicProvider class HubicTests(OAuth2TestsMixin, TestCase): provider_id = HubicProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "email": "user@example.com", "firstname": "Test", "activated": true, "creationDate": "2014-04-17T17:04:01+02:00", "language": "en", "status": "ok", "offer": "25g", "lastname": "User" } """, ) def get_expected_to_str(self): return "user@example.com" def get_login_response_json(self, with_refresh_token=True): return '{\ "access_token": "testac",\ "expires_in": "3600",\ "refresh_token": "testrf",\ "token_type": "Bearer"\ }' django-allauth-65.0.2/allauth/socialaccount/providers/hubic/urls.py000066400000000000000000000002441467545753200254470ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import HubicProvider urlpatterns = default_urlpatterns(HubicProvider) django-allauth-65.0.2/allauth/socialaccount/providers/hubic/views.py000066400000000000000000000020361467545753200256200ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class HubicOAuth2Adapter(OAuth2Adapter): provider_id = "hubic" access_token_url = "https://api.hubic.com/oauth/token" authorize_url = "https://api.hubic.com/oauth/auth" profile_url = "https://api.hubic.com/1.0/account" redirect_uri_protocol = "https" def complete_login(self, request, app, token, **kwargs): token_type = kwargs["response"]["token_type"] resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "%s %s" % (token_type, token.token)}, ) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(HubicOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(HubicOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/hubspot/000077500000000000000000000000001467545753200245025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/hubspot/__init__.py000066400000000000000000000000001467545753200266010ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/hubspot/provider.py000066400000000000000000000020111467545753200267000ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.hubspot.views import HubspotOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class HubspotAccount(ProviderAccount): def to_str(self): return self.account.extra_data.get("user") or super().to_str() class HubspotProvider(OAuth2Provider): id = "hubspot" name = "Hubspot" account_class = HubspotAccount oauth2_adapter_class = HubspotOAuth2Adapter def get_default_scope(self): return ["oauth"] def extract_uid(self, data): return str(data["user_id"]) def extract_common_fields(self, data): return dict(email=data.get("user")) def extract_email_addresses(self, data): ret = [] email = data.get("user") if email: ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [HubspotProvider] django-allauth-65.0.2/allauth/socialaccount/providers/hubspot/tests.py000066400000000000000000000020451467545753200262170ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import HubspotProvider class HubspotTests(OAuth2TestsMixin, TestCase): provider_id = HubspotProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "token": "CNye4dqFMBICAAEYhOKlDZZ_z6IVKI_xMjIUgmFsNQzgBjNE9YBmhAhNOtfN0ak6BAAAAEFCFIIwn2EVRLpvJI9hP4tbIeKHw7ZXSgNldTFSAFoA", "user": "m@acme.com", "hub_domain": "acme.com", "scopes": ["oauth"], "scope_to_scope_group_pks": [25, 31], "trial_scopes": [], "trial_scope_to_scope_group_pks": [], "hub_id": 211580, "app_id": 833572, "expires_in": 1799, "user_id": 42607123, "token_type": "access" }""", ) def get_expected_to_str(self): return "m@acme.com" django-allauth-65.0.2/allauth/socialaccount/providers/hubspot/urls.py000066400000000000000000000002501467545753200260360ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import HubspotProvider urlpatterns = default_urlpatterns(HubspotProvider) django-allauth-65.0.2/allauth/socialaccount/providers/hubspot/views.py000066400000000000000000000021231467545753200262070ustar00rootroot00000000000000"""Views for Hubspot API.""" from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class HubspotOAuth2Adapter(OAuth2Adapter): """OAuth2Adapter for Hubspot API v3.""" provider_id = "hubspot" authorize_url = "https://app.hubspot.com/oauth/authorize" access_token_url = "https://api.hubapi.com/oauth/v1/token" profile_url = "https://api.hubapi.com/oauth/v1/access-tokens" def complete_login(self, request, app, token, **kwargs): headers = {"Content-Type": "application/json"} response = ( get_adapter() .get_requests_session() .get("{0}/{1}".format(self.profile_url, token.token), headers=headers) ) response.raise_for_status() extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(HubspotOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(HubspotOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/instagram/000077500000000000000000000000001467545753200250035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/instagram/__init__.py000066400000000000000000000000001467545753200271020ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/instagram/provider.py000066400000000000000000000016351467545753200272140ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.instagram.views import ( InstagramOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class InstagramAccount(ProviderAccount): PROFILE_URL = "http://instagram.com/" def get_profile_url(self): return self.PROFILE_URL + self.account.extra_data.get("username") class InstagramProvider(OAuth2Provider): id = "instagram" name = "Instagram" account_class = InstagramAccount oauth2_adapter_class = InstagramOAuth2Adapter def extract_extra_data(self, data): return data def get_default_scope(self): return ["user_profile"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict(username=data.get("username")) provider_classes = [InstagramProvider] django-allauth-65.0.2/allauth/socialaccount/providers/instagram/tests.py000066400000000000000000000015361467545753200265240ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import InstagramProvider class InstagramTests(OAuth2TestsMixin, TestCase): provider_id = InstagramProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "username": "georgewhewell", "bio": "", "website": "", "profile_picture": "http://images.ak.instagram.com/profiles/profile_11428116_75sq_1339547159.jpg", "full_name": "georgewhewell", "counts": { "media": 74, "followed_by": 91, "follows": 104 }, "id": "11428116" }""", ) # noqa def get_expected_to_str(self): return "georgewhewell" django-allauth-65.0.2/allauth/socialaccount/providers/instagram/urls.py000066400000000000000000000002541467545753200263430ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import InstagramProvider urlpatterns = default_urlpatterns(InstagramProvider) django-allauth-65.0.2/allauth/socialaccount/providers/instagram/views.py000066400000000000000000000020111467545753200265040ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class InstagramOAuth2Adapter(OAuth2Adapter): provider_id = "instagram" access_token_url = "https://api.instagram.com/oauth/access_token" authorize_url = "https://api.instagram.com/oauth/authorize" profile_url = "https://graph.instagram.com/me" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token, "fields": ["id", "username"]}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(InstagramOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(InstagramOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/jupyterhub/000077500000000000000000000000001467545753200252175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/jupyterhub/__init__.py000066400000000000000000000000001467545753200273160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/jupyterhub/provider.py000066400000000000000000000012361467545753200274250ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.jupyterhub.views import ( JupyterHubOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class JupyterHubAccount(ProviderAccount): pass class JupyterHubProvider(OAuth2Provider): id = "jupyterhub" name = "JupyterHub" account_class = JupyterHubAccount oauth2_adapter_class = JupyterHubOAuth2Adapter def extract_uid(self, data): return str(data.get("name")) def extract_common_fields(self, data): return dict(name=data.get("name", "")) provider_classes = [JupyterHubProvider] django-allauth-65.0.2/allauth/socialaccount/providers/jupyterhub/tests.py000066400000000000000000000013021467545753200267270ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import JupyterHubProvider class JupyterHubTests(OAuth2TestsMixin, TestCase): provider_id = JupyterHubProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "kind": "user", "name": "abc", "admin": false, "groups": [], "server": null, "pending": null, "created": "2016-12-06T18:30:50.297567Z", "last_activity": "2017-02-07T17:29:36.470236Z", "servers": null} """, ) def get_expected_to_str(self): return "abc" django-allauth-65.0.2/allauth/socialaccount/providers/jupyterhub/urls.py000066400000000000000000000003401467545753200265530ustar00rootroot00000000000000from allauth.socialaccount.providers.jupyterhub.provider import ( JupyterHubProvider, ) from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(JupyterHubProvider) django-allauth-65.0.2/allauth/socialaccount/providers/jupyterhub/views.py000066400000000000000000000023131467545753200267250ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class JupyterHubOAuth2Adapter(OAuth2Adapter): provider_id = "jupyterhub" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("API_URL", "") access_token_url = "{0}/hub/api/oauth2/token".format(provider_base_url) authorize_url = "{0}/hub/api/oauth2/authorize".format(provider_base_url) profile_url = "{0}/hub/api/user".format(provider_base_url) def complete_login(self, request, app, token: SocialToken, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} extra_data = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) user_profile = extra_data.json() return self.get_provider().sociallogin_from_response(request, user_profile) oauth2_login = OAuth2LoginView.adapter_view(JupyterHubOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(JupyterHubOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/kakao/000077500000000000000000000000001467545753200241045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/kakao/__init__.py000066400000000000000000000000001467545753200262030ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/kakao/models.py000066400000000000000000000000001467545753200257270ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/kakao/provider.py000066400000000000000000000031741467545753200263150ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.kakao.views import KakaoOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class KakaoAccount(ProviderAccount): @property def properties(self): return self.account.extra_data.get("properties", {}) @property def profile(self): return self.account.extra_data.get("kakao_account", {}).get("profile", {}) def get_avatar_url(self): return self.profile.get( "profile_image_url", self.properties.get("profile_image") ) def get_user_data(self): return self.account.extra_data.get("kakao_account") class KakaoProvider(OAuth2Provider): id = "kakao" name = "Kakao" account_class = KakaoAccount oauth2_adapter_class = KakaoOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): email = data.get("kakao_account", {}).get("email") nickname = data.get("kakao_account", {}).get("profile", {}).get("nickname") return dict(email=email, username=nickname) def extract_email_addresses(self, data): ret = [] data = data.get("kakao_account", {}) email = data.get("email") if email: verified = data.get("is_email_verified") # data['is_email_verified'] imply the email address is # verified ret.append(EmailAddress(email=email, verified=verified, primary=True)) return ret provider_classes = [KakaoProvider] django-allauth-65.0.2/allauth/socialaccount/providers/kakao/tests.py000066400000000000000000000041701467545753200256220ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import KakaoProvider class KakaoTests(OAuth2TestsMixin, TestCase): provider_id = KakaoProvider.id kakao_data = """ { "id": 123456789, "connected_at": "2022-04-11T01:45:28Z", "kakao_account": { "profile_nickname_needs_agreement": false, "profile_image_needs_agreement": false, "profile": { "nickname": "홍길동", "thumbnail_image_url": "http://yyy.kakao.com/.../img_110x110.jpg", "profile_image_url": "http://yyy.kakao.com/dn/.../img_640x640.jpg", "is_default_image":false, "is_default_nickname": false }, "name_needs_agreement":false, "name":"홍길동", "email_needs_agreement":false, "is_email_valid": true, "is_email_verified": true, "email": "sample@sample.com", "age_range_needs_agreement":false, "age_range":"20~29", "birthyear_needs_agreement": false, "birthyear": "2002", "birthday_needs_agreement":false, "birthday":"1130", "birthday_type":"SOLAR", "gender_needs_agreement":false, "gender":"female", "phone_number_needs_agreement": false, "phone_number": "+82 010-1234-5678", "ci_needs_agreement": false, "ci": "CI", "ci_authenticated_at": "2019-03-11T11:25:22Z" }, "properties":{ "CUSTOM_PROPERTY_KEY": "CUSTOM_PROPERTY_VALUE" }, "for_partner": { "uuid": "UUID" } } """ def get_expected_to_str(self): return "sample@sample.com" def get_mocked_response(self, data=None): if data is None: data = self.kakao_data return MockedResponse(200, data) django-allauth-65.0.2/allauth/socialaccount/providers/kakao/urls.py000066400000000000000000000002441467545753200254430ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import KakaoProvider urlpatterns = default_urlpatterns(KakaoProvider) django-allauth-65.0.2/allauth/socialaccount/providers/kakao/views.py000066400000000000000000000016731467545753200256220ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class KakaoOAuth2Adapter(OAuth2Adapter): provider_id = "kakao" access_token_url = "https://kauth.kakao.com/oauth/token" authorize_url = "https://kauth.kakao.com/oauth/authorize" profile_url = "https://kapi.kakao.com/v2/user/me" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(KakaoOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(KakaoOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/lemonldap/000077500000000000000000000000001467545753200247715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/lemonldap/__init__.py000066400000000000000000000000001467545753200270700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/lemonldap/provider.py000066400000000000000000000017041467545753200271770ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.lemonldap.views import ( LemonLDAPOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class LemonLDAPAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("picture") class LemonLDAPProvider(OAuth2Provider): id = "lemonldap" name = "LemonLDAP::NG" account_class = LemonLDAPAccount oauth2_adapter_class = LemonLDAPOAuth2Adapter def get_default_scope(self): return ["openid", "profile", "email"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("preferred_username"), name=data.get("name"), picture=data.get("picture"), ) provider_classes = [LemonLDAPProvider] django-allauth-65.0.2/allauth/socialaccount/providers/lemonldap/tests.py000066400000000000000000000012351467545753200265060ustar00rootroot00000000000000from allauth.socialaccount.providers.lemonldap.provider import ( LemonLDAPProvider, ) from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class LemonLDAPTests(OAuth2TestsMixin, TestCase): provider_id = LemonLDAPProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "email": "dwho@example.com", "sub": "dwho", "preferred_username": "dwho", "name": "Doctor Who" } """, ) def get_expected_to_str(self): return "dwho@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/lemonldap/urls.py000066400000000000000000000003351467545753200263310ustar00rootroot00000000000000from allauth.socialaccount.providers.lemonldap.provider import ( LemonLDAPProvider, ) from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(LemonLDAPProvider) django-allauth-65.0.2/allauth/socialaccount/providers/lemonldap/views.py000066400000000000000000000024311467545753200265000ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class LemonLDAPOAuth2Adapter(OAuth2Adapter): provider_id = "lemonldap" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("LEMONLDAP_URL") access_token_url = "{0}/oauth2/token".format(provider_base_url) authorize_url = "{0}/oauth2/authorize".format(provider_base_url) profile_url = "{0}/oauth2/userinfo".format(provider_base_url) def complete_login(self, request, app, token: SocialToken, **kwargs): response = ( get_adapter() .get_requests_session() .post(self.profile_url, headers={"Authorization": "Bearer " + token.token}) ) response.raise_for_status() extra_data = response.json() extra_data["id"] = extra_data["sub"] del extra_data["sub"] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(LemonLDAPOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(LemonLDAPOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/lichess/000077500000000000000000000000001467545753200244505ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/lichess/__init__.py000066400000000000000000000000001467545753200265470ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/lichess/provider.py000066400000000000000000000030751467545753200266610ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.lichess.views import LichessOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class LichessAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("url") def get_avatar_url(self): return self.account.extra_data.get("avatar") class LichessProvider(OAuth2Provider): id = "lichess" name = "Lichess" account_class = LichessAccount oauth2_adapter_class = LichessOAuth2Adapter pkce_enabled_default = True def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): first_name = data.get("profile", {}).get("firstName") last_name = data.get("profile", {}).get("lastName") return dict( username=data.get("username"), email=data.get("email"), first_name=first_name, last_name=last_name, ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: ret.append( EmailAddress( email=email, primary=True, ) ) return ret def get_default_scope(self): ret = [] if QUERY_EMAIL: ret.append("email:read") return ret provider_classes = [LichessProvider] django-allauth-65.0.2/allauth/socialaccount/providers/lichess/tests.py000066400000000000000000000031251467545753200261650ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import LichessProvider class LichessTests(OAuth2TestsMixin, TestCase): provider_id = LichessProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """ { "id": "george", "url": "https://lichess.org/@/george", "count": { "ai": 0, "me": 0, "all": 0, "win": 0, "draw": 0, "loss": 0, "winH": 0, "drawH": 0, "lossH": 0, "rated": 0, "import": 0, "playing": 0, "bookmark": 0 }, "perfs": { "blitz": { "rd": 500, "prog": 0, "prov": true, "games": 0, "rating": 1500 }, "rapid": { "rd": 500, "prog": 0, "prov": true, "games": 0, "rating": 1500 }, "bullet": { "rd": 500, "prog": 0, "prov": true, "games": 0, "rating": 1500 }, "classical": { "rd": 500, "prog": 0, "prov": true, "games": 0, "rating": 1500 }, "correspondence": { "rd": 500, "prog": 0, "prov": true, "games": 0, "rating": 1500 } }, "seenAt": 1713837454330, "blocking": false, "playTime": { "tv": 0, "total": 0 }, "username": "george", "createdAt": 1713837409417, "following": false, "followable": true, "followsYou": false } """, ), MockedResponse(200, """{"email":"george@example.com"}"""), ] def get_expected_to_str(self): return "george" django-allauth-65.0.2/allauth/socialaccount/providers/lichess/urls.py000066400000000000000000000002501467545753200260040ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import LichessProvider urlpatterns = default_urlpatterns(LichessProvider) django-allauth-65.0.2/allauth/socialaccount/providers/lichess/views.py000066400000000000000000000037771467545753200261750ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class LichessOAuth2Adapter(OAuth2Adapter): provider_id = "lichess" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("API_URL", "https://lichess.org") access_token_url = f"{provider_base_url}/api/token" authorize_url = f"{provider_base_url}/oauth" profile_url = f"{provider_base_url}/api/account" email_address_url = f"{provider_base_url}/api/account/email" def complete_login(self, request, app, token, response): profile_res = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token}, headers={"Authorization": f"Bearer {token.token}"}, ) ) profile_res.raise_for_status() extra_data = profile_res.json() user_profile = extra_data["result"] if "result" in extra_data else extra_data # retrieve email address if requested if QUERY_EMAIL: email_data = ( get_adapter() .get_requests_session() .get( self.email_address_url, headers={"Authorization": f"Bearer {token.token}"}, ) ) email_data.raise_for_status() email_data = email_data.json() # extract email address from response email = email_data.get("email", None) if email: user_profile["email"] = email return self.get_provider().sociallogin_from_response(request, user_profile) oauth2_login = OAuth2LoginView.adapter_view(LichessOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(LichessOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/line/000077500000000000000000000000001467545753200237455ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/line/__init__.py000066400000000000000000000000001467545753200260440ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/line/models.py000066400000000000000000000000001467545753200255700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/line/provider.py000066400000000000000000000020141467545753200261460ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.line.views import LineOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class LineAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("pictureUrl") or self.account.extra_data.get( "picture" ) class LineProvider(OAuth2Provider): id = "line" name = "Line" account_class = LineAccount oauth2_adapter_class = LineOAuth2Adapter def get_default_scope(self): return [] def extract_uid(self, data): return str(data.get("userId") or data.get("sub")) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("email") or self.extract_uid(data), first_name=data.get("first_name"), last_name=data.get("last_name"), name=data.get("name"), ) provider_classes = [LineProvider] django-allauth-65.0.2/allauth/socialaccount/providers/line/tests.py000066400000000000000000000011211467545753200254540ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import LineProvider class LineTests(OAuth2TestsMixin, TestCase): provider_id = LineProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "userId": "u7d47d26a6bab09b95695ff02d1a36e38", "displayName": "\uc774\uc0c1\ud601", "pictureUrl": "http://dl.profile.line-cdn.net/0m055ab14d725138288331268c45ac5286a35482fb794a" }""", ) def get_expected_to_str(self): return "\uc774\uc0c1\ud601" django-allauth-65.0.2/allauth/socialaccount/providers/line/urls.py000066400000000000000000000002421467545753200253020ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import LineProvider urlpatterns = default_urlpatterns(LineProvider) django-allauth-65.0.2/allauth/socialaccount/providers/line/views.py000066400000000000000000000043301467545753200254540ustar00rootroot00000000000000from datetime import timedelta from django.utils import timezone from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class LineOAuth2Adapter(OAuth2Adapter): provider_id = "line" access_token_url = "https://api.line.me/oauth2/v2.1/token" authorize_url = "https://access.line.me/oauth2/v2.1/authorize" profile_url = "https://api.line.me/v2/profile" # https://developers.line.biz/en/reference/line-login/#get-user-profile id_token_url = "https://api.line.me/oauth2/v2.1/verify" # https://developers.line.biz/en/reference/line-login/#verify-id-token def parse_token(self, data): """ data: access_token data from line """ settings = app_settings.PROVIDERS.get(self.provider_id, {}) if "email" in settings.get("SCOPE", ""): token = SocialToken(token=data["id_token"]) else: token = SocialToken(token=data["access_token"]) token.token_secret = data.get("refresh_token", "") expires_in = data.get(self.expires_in_key, None) if expires_in: token.expires_at = timezone.now() + timedelta(seconds=int(expires_in)) return token def complete_login(self, request, app, token, **kwargs): settings = app_settings.PROVIDERS.get(self.provider_id, {}) if "email" in settings.get("SCOPE", ""): payload = {"client_id": app.client_id, "id_token": token.token} resp = get_adapter().get_requests_session().post(self.id_token_url, payload) else: headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter() .get_requests_session() .get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(LineOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(LineOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/linkedin_oauth2/000077500000000000000000000000001467545753200260755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/linkedin_oauth2/__init__.py000066400000000000000000000000001467545753200301740ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/linkedin_oauth2/provider.py000066400000000000000000000127711467545753200303110ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ( ProviderAccount, ProviderException, ) from allauth.socialaccount.providers.linkedin_oauth2.views import ( LinkedInOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider def _extract_name_field(data, field_name): ret = "" v = data.get(field_name, {}) if v: if isinstance(v, str): # Old V1 data ret = v else: localized = v.get("localized", {}) preferred_locale = v.get( "preferredLocale", {"country": "US", "language": "en"} ) locale_key = "_".join( [preferred_locale["language"], preferred_locale["country"]] ) if locale_key in localized: ret = localized.get(locale_key) elif localized: ret = next(iter(localized.values())) return ret def _extract_email(data): """ {'elements': [{'handle': 'urn:li:emailAddress:319371470', 'handle~': {'emailAddress': 'raymond.penners@intenct.nl'}}]} """ ret = "" elements = data.get("elements", []) if len(elements) > 0: ret = elements[0].get("handle~", {}).get("emailAddress", "") return ret class LinkedInOAuth2Account(ProviderAccount): def to_str(self): ret = super(LinkedInOAuth2Account, self).to_str() if self.account.extra_data.get("emailAddress"): return self.account.extra_data["emailAddress"] first_name = _extract_name_field(self.account.extra_data, "firstName") last_name = _extract_name_field(self.account.extra_data, "lastName") if first_name or last_name: ret = " ".join([first_name, last_name]).strip() return ret def get_avatar_url(self): """ Attempts the load the avatar associated to the avatar. Requires the `profilePicture(displayImage~:playableStreams)` profile field configured in settings.py :return: """ provider_configuration = self.account.get_provider().get_settings() configured_profile_fields = provider_configuration.get("PROFILE_FIELDS", []) # Can't get the avatar when this field is not specified picture_field = "profilePicture(displayImage~:playableStreams)" if picture_field not in configured_profile_fields: return super(LinkedInOAuth2Account, self).get_avatar_url() # Iterate over the fields and attempt to get it by configured size profile_picture_config = provider_configuration.get("PROFILEPICTURE", {}) req_size = profile_picture_config.get("display_size_w_h", (100.0, 100.0)) req_auth_method = profile_picture_config.get("authorization_method", "PUBLIC") # Iterate over the data returned by the provider profile_elements = ( self.account.extra_data.get("profilePicture", {}) .get("displayImage~", {}) .get("elements", []) ) for single_element in profile_elements: if not req_auth_method == single_element["authorizationMethod"]: continue # Get the dimensions from the payload image_data = ( single_element.get("data", {}) .get("com.linkedin.digitalmedia.mediaartifact.StillImage", {}) .get("displaySize", {}) ) if not image_data: continue width, height = image_data["width"], image_data["height"] if not width or not height: continue if not width == req_size[0] or not height == req_size[1]: continue # Get the uri since actual size matches the requested size. to_return = single_element.get( "identifiers", [ {}, ], )[ 0 ].get("identifier") if to_return: return to_return return super(LinkedInOAuth2Account, self).get_avatar_url() class LinkedInOAuth2Provider(OAuth2Provider): id = "linkedin_oauth2" # Name is displayed to ordinary users -- don't include protocol name = "LinkedIn" account_class = LinkedInOAuth2Account oauth2_adapter_class = LinkedInOAuth2Adapter def extract_uid(self, data): if "id" not in data: raise ProviderException( "LinkedIn encountered an internal error while logging in. \ Please try again." ) return str(data["id"]) def get_profile_fields(self): default_fields = [ "id", "firstName", "lastName", # This would be needed to in case you need access to the image # URL. Not enabling this by default due to the amount of data # returned. # # 'profilePicture(displayImage~:playableStreams)' ] fields = self.get_settings().get("PROFILE_FIELDS", default_fields) return fields def get_default_scope(self): scope = ["r_liteprofile"] if app_settings.QUERY_EMAIL: scope.append("r_emailaddress") return scope def extract_common_fields(self, data): return dict( first_name=_extract_name_field(data, "firstName"), last_name=_extract_name_field(data, "lastName"), email=_extract_email(data), ) provider_classes = [LinkedInOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/linkedin_oauth2/tests.py000066400000000000000000000332551467545753200276210ustar00rootroot00000000000000from json import loads from django.test.utils import override_settings from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.base import ProviderException from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import LinkedInOAuth2Provider class LinkedInOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = LinkedInOAuth2Provider.id def get_mocked_response(self): return [ MockedResponse( 200, """ {} """, ), MockedResponse( 200, """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } } } """, ), ] def get_expected_to_str(self): return "Raymond Penners" def test_data_to_str(self): data = { "emailAddress": "john@doe.org", "firstName": "John", "id": "a1b2c3d4e", "lastName": "Doe", "pictureUrl": "https://media.licdn.com/mpr/foo", "pictureUrls": { "_total": 1, "values": ["https://media.licdn.com/foo"], }, "publicProfileUrl": "https://www.linkedin.com/in/johndoe", } acc = SocialAccount(extra_data=data, provider="linkedin_oauth2") self.assertEqual(acc.get_provider_account().to_str(), "john@doe.org") def test_get_avatar_url_no_picture_setting(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } } } """ acc = SocialAccount( extra_data=loads(extra_data), provider="linkedin_oauth2", ) self.assertIsNone(acc.get_avatar_url()) @override_settings( SOCIALACCOUNT_PROVIDERS={ "linkedin_oauth2": { "PROFILE_FIELDS": [ "id", "firstName", "lastName", "profilePicture(displayImage~:playableStreams)", ], "PROFILEPICTURE": { "display_size_w_h": (400, 400.0), }, }, } ) def test_get_avatar_url_with_setting(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } } } """ acc = SocialAccount( extra_data=loads(extra_data), provider="linkedin_oauth2", ) self.assertIsNone(acc.get_avatar_url()) @override_settings( SOCIALACCOUNT_PROVIDERS={ "linkedin_oauth2": { "PROFILE_FIELDS": [ "id", "firstName", "lastName", "profilePicture(displayImage~:playableStreams)", ], "PROFILEPICTURE": { "display_size_w_h": (100, 100.0), }, }, } ) def test_get_avatar_url_with_picture(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } }, "profilePicture": { "displayImage~": { "elements": [ { "authorizationMethod": "PUBLIC", "data": { "com.linkedin.digitalmedia.mediaartifact.StillImage": { "storageSize": { "height": 100, "width": 100 }, "storageAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "displaySize": { "height": 100.0, "width": 100.0, "uom": "PX" }, "rawCodecSpec": { "name": "jpeg", "type": "image" }, "displayAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "mediaType": "image/jpeg" } }, "artifact": "urn:li:digitalmediaMediaArtifact:avatar", "identifiers": [ { "identifierExpiresInSeconds": 4, "file": "urn:li:digitalmediaFile:this-is-the-link", "index": 0, "identifier": "this-is-the-link", "mediaType": "image/jpeg", "identifierType": "EXTERNAL_URL" } ] } ] } } } """ acc = SocialAccount( extra_data=loads(extra_data), provider="linkedin_oauth2", ) self.assertEqual("this-is-the-link", acc.get_avatar_url()) @override_settings( SOCIALACCOUNT_PROVIDERS={ "linkedin_oauth2": { "PROFILE_FIELDS": [ "id", "firstName", "lastName", "profilePicture(displayImage~:playableStreams)", ], "PROFILEPICTURE": { "display_size_w_h": (400, 400.0), }, }, } ) def test_get_avatar_url_size_mismatch(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } }, "profilePicture": { "displayImage~": { "elements": [ { "authorizationMethod": "PUBLIC", "data": { "com.linkedin.digitalmedia.mediaartifact.StillImage": { "storageSize": { "height": 100, "width": 100 }, "storageAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "displaySize": { "height": 100.0, "width": 100.0, "uom": "PX" }, "rawCodecSpec": { "name": "jpeg", "type": "image" }, "displayAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "mediaType": "image/jpeg" } }, "artifact": "urn:li:digitalmediaMediaArtifact:avatar", "identifiers": [ { "identifierExpiresInSeconds": 4, "file": "urn:li:digitalmediaFile:this-is-the-link", "index": 0, "identifier": "this-is-the-link", "mediaType": "image/jpeg", "identifierType": "EXTERNAL_URL" } ] } ] } } } """ acc = SocialAccount( extra_data=loads(extra_data), provider="linkedin_oauth2", ) self.assertIsNone(acc.get_avatar_url()) @override_settings( SOCIALACCOUNT_PROVIDERS={ "linkedin_oauth2": { "PROFILE_FIELDS": [ "id", "firstName", "lastName", "profilePicture(displayImage~:playableStreams)", ], "PROFILEPICTURE": { "display_size_w_h": (400, 400.0), }, }, } ) def test_get_avatar_url_auth_mismatch(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } }, "profilePicture": { "displayImage~": { "elements": [ { "authorizationMethod": "PRIVATE", "data": { "com.linkedin.digitalmedia.mediaartifact.StillImage": { "storageSize": { "height": 100, "width": 100 }, "storageAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "displaySize": { "height": 100.0, "width": 100.0, "uom": "PX" }, "rawCodecSpec": { "name": "jpeg", "type": "image" }, "displayAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "mediaType": "image/jpeg" } }, "artifact": "urn:li:digitalmediaMediaArtifact:avatar", "identifiers": [ { "identifierExpiresInSeconds": 4, "file": "urn:li:digitalmediaFile:this-is-the-link", "index": 0, "identifier": "this-is-the-link", "mediaType": "image/jpeg", "identifierType": "EXTERNAL_URL" } ] } ] } } } """ acc = SocialAccount( extra_data=loads(extra_data), provider="linkedin_oauth2", ) self.assertIsNone(acc.get_avatar_url()) @override_settings( SOCIALACCOUNT_PROVIDERS={ "linkedin_oauth2": { "PROFILE_FIELDS": [ "id", "firstName", "lastName", "profilePicture(displayImage~:playableStreams)", ], "PROFILEPICTURE": { "display_size_w_h": (100, 100), }, }, } ) def test_get_avatar_url_float_vs_int(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } }, "profilePicture": { "displayImage~": { "elements": [ { "authorizationMethod": "PUBLIC", "data": { "com.linkedin.digitalmedia.mediaartifact.StillImage": { "storageSize": { "height": 100, "width": 100 }, "storageAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "displaySize": { "height": 100.0, "width": 100.0, "uom": "PX" }, "rawCodecSpec": { "name": "jpeg", "type": "image" }, "displayAspectRatio": { "heightAspect": 1.0, "formatted": "1.00:1.00", "widthAspect": 1.0 }, "mediaType": "image/jpeg" } }, "artifact": "urn:li:digitalmediaMediaArtifact:avatar", "identifiers": [ { "identifierExpiresInSeconds": 4, "file": "urn:li:digitalmediaFile:this-is-the-link", "index": 0, "identifier": "this-is-the-link", "mediaType": "image/jpeg", "identifierType": "EXTERNAL_URL" } ] } ] } } } """ acc = SocialAccount( extra_data=loads(extra_data), provider="linkedin_oauth2", ) self.assertEqual("this-is-the-link", acc.get_avatar_url()) def test_id_missing(self): extra_data = """ { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "Id": "1234567" } """ self.assertRaises( ProviderException, self.provider.extract_uid, loads(extra_data) ) django-allauth-65.0.2/allauth/socialaccount/providers/linkedin_oauth2/urls.py000066400000000000000000000002661467545753200274400ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import LinkedInOAuth2Provider urlpatterns = default_urlpatterns(LinkedInOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/linkedin_oauth2/views.py000066400000000000000000000037121467545753200276070ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class LinkedInOAuth2Adapter(OAuth2Adapter): provider_id = "linkedin_oauth2" access_token_url = "https://www.linkedin.com/oauth/v2/accessToken" authorize_url = "https://www.linkedin.com/oauth/v2/authorization" profile_url = "https://api.linkedin.com/v2/me" email_url = "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))" # noqa # See: # http://developer.linkedin.com/forum/unauthorized-invalid-or-expired-token-immediately-after-receiving-oauth2-token?page=1 # noqa access_token_method = "GET" def complete_login(self, request, app, token, **kwargs): extra_data = self.get_user_info(token) return self.get_provider().sociallogin_from_response(request, extra_data) def get_user_info(self, token): fields = self.get_provider().get_profile_fields() headers = {} headers.update(self.get_provider().get_settings().get("HEADERS", {})) headers["Authorization"] = " ".join(["Bearer", token.token]) info = {} if app_settings.QUERY_EMAIL: resp = ( get_adapter() .get_requests_session() .get(self.email_url, headers=headers) ) # If this response goes wrong, that is not a blocker in order to # continue. if resp.ok: info = resp.json() url = self.profile_url + "?projection=(%s)" % ",".join(fields) resp = get_adapter().get_requests_session().get(url, headers=headers) resp.raise_for_status() info.update(resp.json()) return info oauth2_login = OAuth2LoginView.adapter_view(LinkedInOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(LinkedInOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/mailchimp/000077500000000000000000000000001467545753200247615ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/mailchimp/__init__.py000066400000000000000000000000001467545753200270600ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/mailchimp/provider.py000066400000000000000000000033251467545753200271700ustar00rootroot00000000000000"""Customise Provider classes for MailChimp API v3.""" from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.mailchimp.views import ( MailChimpOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class MailChimpAccount(ProviderAccount): """ProviderAccount subclass for MailChimp.""" def get_profile_url(self): """Return base profile url.""" return self.account.extra_data["api_endpoint"] def get_avatar_url(self): """Return avatar url.""" return self.account.extra_data["login"]["avatar"] def to_str(self): dflt = super().to_str() login_data = self.account.extra_data.get("login", {}) return login_data.get("login_email") or login_data.get("email") or dflt class MailChimpProvider(OAuth2Provider): """OAuth2Provider subclass for MailChimp v3.""" id = "mailchimp" name = "MailChimp" account_class = MailChimpAccount oauth2_adapter_class = MailChimpOAuth2Adapter def extract_uid(self, data): """Extract uid ('user_id') and ensure it's a str.""" return str(data["user_id"]) def get_default_scope(self): """Ensure scope is null to fit their API.""" return [""] def extract_common_fields(self, data): """Extract fields from a metadata query.""" return dict( dc=data.get("dc"), role=data.get("role"), account_name=data.get("accountname"), user_id=data.get("user_id"), login=data.get("login"), login_url=data.get("login_url"), api_endpoint=data.get("api_endpoint"), ) provider_classes = [MailChimpProvider] django-allauth-65.0.2/allauth/socialaccount/providers/mailchimp/tests.py000066400000000000000000000021611467545753200264750ustar00rootroot00000000000000"""Test MailChimp OAuth2 v3 Flow.""" from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import MailChimpProvider class MailChimpTests(OAuth2TestsMixin, TestCase): """Test Class for MailChimp OAuth2 v3.""" provider_id = MailChimpProvider.id def get_mocked_response(self): """Test authentication with an non-null avatar.""" return MockedResponse( 200, """{ "dc": "usX", "role": "owner", "accountname": "Name can have spaces", "user_id": "99999999", "login": { "email": "test@example.com", "avatar": "http://gallery.mailchimp.com/1a1a/avatar/2a2a.png", "login_id": "88888888", "login_name": "test@example.com", "login_email": "test@example.com" }, "login_url": "https://login.mailchimp.com", "api_endpoint": "https://usX.api.mailchimp.com" }""", ) def get_expected_to_str(self): return "test@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/mailchimp/urls.py000066400000000000000000000003271467545753200263220ustar00rootroot00000000000000"""Register urls for MailChimpProvider""" from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import MailChimpProvider urlpatterns = default_urlpatterns(MailChimpProvider) django-allauth-65.0.2/allauth/socialaccount/providers/mailchimp/views.py000066400000000000000000000021251467545753200264700ustar00rootroot00000000000000"""Views for MailChimp API v3.""" from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class MailChimpOAuth2Adapter(OAuth2Adapter): """OAuth2Adapter for MailChimp API v3.""" provider_id = "mailchimp" authorize_url = "https://login.mailchimp.com/oauth2/authorize" access_token_url = "https://login.mailchimp.com/oauth2/token" profile_url = "https://login.mailchimp.com/oauth2/metadata" def complete_login(self, request, app, token, **kwargs): """Complete login, ensuring correct OAuth header.""" headers = {"Authorization": "OAuth {0}".format(token.token)} metadata = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = metadata.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(MailChimpOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(MailChimpOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/mailru/000077500000000000000000000000001467545753200243075ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/mailru/__init__.py000066400000000000000000000000001467545753200264060ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/mailru/provider.py000066400000000000000000000023351467545753200265160ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.mailru.views import MailRuOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class MailRuAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("link") def get_avatar_url(self): ret = None if self.account.extra_data.get("has_pic"): pic_big_url = self.account.extra_data.get("pic_big") pic_small_url = self.account.extra_data.get("pic_small") if pic_big_url: return pic_big_url elif pic_small_url: return pic_small_url else: return ret class MailRuProvider(OAuth2Provider): id = "mailru" name = "Mail.RU" account_class = MailRuAccount oauth2_adapter_class = MailRuOAuth2Adapter def extract_uid(self, data): return data["uid"] def extract_common_fields(self, data): return dict( email=data.get("email"), last_name=data.get("last_name"), username=data.get("nick"), first_name=data.get("first_name"), ) provider_classes = [MailRuProvider] django-allauth-65.0.2/allauth/socialaccount/providers/mailru/tests.py000066400000000000000000000027601467545753200260300ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import MailRuProvider class MailRuTests(OAuth2TestsMixin, TestCase): provider_id = MailRuProvider.id def get_mocked_response(self, verified_email=True): return MockedResponse( 200, """ [ { "uid": "15410773191172635989", "first_name": "Евгений", "last_name": "Маслов", "nick": "maslov", "email": "emaslov@mail.ru", "sex": 0, "birthday": "15.02.1980", "has_pic": 1, "pic": "http://avt.appsmail.ru/mail/emaslov/_avatar", "pic_small": "http://avt.appsmail.ru/mail/emaslov/_avatarsmall", "pic_big": "http://avt.appsmail.ru/mail/emaslov/_avatarbig", "link": "http://my.mail.ru/mail/emaslov/", "referer_type": "", "referer_id": "", "is_online": 1, "friends_count": 145, "is_verified": 1, "vip" : 0, "app_installed": 1, "location": { "country": { "name": "Россия", "id": "24" }, "city": { "name": "Москва", "id": "25" }, "region": { "name": "Москва", "id": "999999" } } }]""", ) # noqa def get_login_response_json(self, with_refresh_token=True): # TODO: This is not an actual response. I added this in order # to get the test suite going but did not verify to check the # exact response being returned. return '{"access_token": "testac", "uid": "weibo", "refresh_token": "testrf", "x_mailru_vid": "1"}' # noqa def get_expected_to_str(self): return "emaslov@mail.ru" django-allauth-65.0.2/allauth/socialaccount/providers/mailru/urls.py000066400000000000000000000002461467545753200256500ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import MailRuProvider urlpatterns = default_urlpatterns(MailRuProvider) django-allauth-65.0.2/allauth/socialaccount/providers/mailru/views.py000066400000000000000000000023771467545753200260270ustar00rootroot00000000000000from hashlib import md5 from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class MailRuOAuth2Adapter(OAuth2Adapter): provider_id = "mailru" access_token_url = "https://connect.mail.ru/oauth/token" authorize_url = "https://connect.mail.ru/oauth/authorize" profile_url = "http://www.appsmail.ru/platform/api" def complete_login(self, request, app, token, **kwargs): uid = kwargs["response"]["x_mailru_vid"] data = { "method": "users.getInfo", "app_id": app.client_id, "secure": "1", "uids": uid, } param_list = sorted([item + "=" + data[item] for item in data]) data["sig"] = md5( ("".join(param_list) + app.secret).encode("utf-8") ).hexdigest() response = ( get_adapter().get_requests_session().get(self.profile_url, params=data) ) extra_data = response.json()[0] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(MailRuOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(MailRuOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/mediawiki/000077500000000000000000000000001467545753200247615ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/mediawiki/__init__.py000066400000000000000000000000001467545753200270600ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/mediawiki/provider.py000066400000000000000000000033631467545753200271720ustar00rootroot00000000000000from typing import Optional from django.conf import settings from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.mediawiki.views import ( MediaWikiOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider settings = getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}).get("mediawiki", {}) class MediaWikiAccount(ProviderAccount): def get_profile_url(self): userpage = settings.get( "USERPAGE_TEMPLATE", "https://meta.wikimedia.org/wiki/User:{username}" ) username = self.account.extra_data.get("username") if not username: return None return userpage.format(username=username.replace(" ", "_")) class MediaWikiProvider(OAuth2Provider): id = "mediawiki" name = "MediaWiki" account_class = MediaWikiAccount oauth2_adapter_class = MediaWikiOAuth2Adapter @staticmethod def _get_email(data: dict) -> Optional[str]: if data.get("confirmed_email"): return data.get("email") return None def extract_uid(self, data): return str(data["sub"]) def extract_extra_data(self, data): return dict( email=self._get_email(data), realname=data.get("realname"), username=data.get("username"), ) def extract_common_fields(self, data): return dict( email=self._get_email(data), username=data.get("username"), name=data.get("realname"), ) def extract_email_addresses(self, data): return [EmailAddress(email=self._get_email(data), verified=True, primary=True)] provider_classes = [MediaWikiProvider] django-allauth-65.0.2/allauth/socialaccount/providers/mediawiki/tests.py000066400000000000000000000021121467545753200264710ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import MediaWikiProvider class MediaWikiTests(OAuth2TestsMixin, TestCase): provider_id = MediaWikiProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "iss": "https://meta.wikimedia.org", "sub": 12345, "aud": "1234567890abcdef", "exp": 946681300, "iat": 946681200, "username": "John Doe", "editcount": 123, "confirmed_email": true, "blocked": false, "registered": "20000101000000", "groups": ["*", "user", "autoconfirmed"], "rights": ["read", "edit"], "grants": ["basic"], "email": "johndoe@example.com" } """, ) def get_expected_to_str(self): return "John Doe" django-allauth-65.0.2/allauth/socialaccount/providers/mediawiki/urls.py000066400000000000000000000002541467545753200263210ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import MediaWikiProvider urlpatterns = default_urlpatterns(MediaWikiProvider) django-allauth-65.0.2/allauth/socialaccount/providers/mediawiki/views.py000066400000000000000000000023511467545753200264710ustar00rootroot00000000000000from django.conf import settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) provider_settings: dict = getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}).get( "mediawiki", {} ) class MediaWikiOAuth2Adapter(OAuth2Adapter): provider_id = "mediawiki" REST_API = provider_settings.get( "REST_API", "https://meta.wikimedia.org/w/rest.php" ) access_token_url = REST_API + "/oauth2/access_token" authorize_url = REST_API + "/oauth2/authorize" profile_url = REST_API + "/oauth2/resource/profile" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer {token}".format(token=token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(MediaWikiOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(MediaWikiOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/meetup/000077500000000000000000000000001467545753200243155ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/meetup/__init__.py000066400000000000000000000000001467545753200264140ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/meetup/models.py000066400000000000000000000000001467545753200261400ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/meetup/provider.py000066400000000000000000000012001467545753200265120ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.meetup.views import MeetupOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class MeetupAccount(ProviderAccount): pass class MeetupProvider(OAuth2Provider): id = "meetup" name = "Meetup" account_class = MeetupAccount oauth2_adapter_class = MeetupOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict(email=data.get("email"), name=data.get("name")) provider_classes = [MeetupProvider] django-allauth-65.0.2/allauth/socialaccount/providers/meetup/tests.py000066400000000000000000000027701467545753200260370ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import MeetupProvider class MeetupTests(OAuth2TestsMixin, TestCase): provider_id = MeetupProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"id": 1, "lang": "en_US", "city": "Bhubaneswar", "photo": { "thumb_link":"", "photo_id": 240057062, "highres_link":"", "base_url": "http://photos2.meetupstatic.com", "type": "member", "name": "Abhishek Jaiswal", "other_services": {}, "country": "in", "topics": [{"name": "Open Source", "urlkey": "opensource", "id": 563}, {"name": "Python", "urlkey": "python", "id": 1064}, {"name": "Software Development", "urlkey": "softwaredev", "id": 3833}, {"name": "Computer programming", "urlkey": "computer-programming", "id": 48471}, {"name": "Python Web Development", "urlkey": "python-web-development", "id": 917242}, {"name": "Data Science using Python", "urlkey": "data-science-using-python", "id": 1481522}], "lon": 85.83999633789062, "joined": 1411642310000, "id": 173662372, "status": "active", "link": "http://www.meetup.com/members/173662372", "hometown": "Kolkata", "lat": 20.270000457763672, "visited": 1488829924000, "self": {"common": {}}}}""", ) def get_expected_to_str(self): return "Meetup" django-allauth-65.0.2/allauth/socialaccount/providers/meetup/urls.py000066400000000000000000000002461467545753200256560ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import MeetupProvider urlpatterns = default_urlpatterns(MeetupProvider) django-allauth-65.0.2/allauth/socialaccount/providers/meetup/views.py000066400000000000000000000016221467545753200260250ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class MeetupOAuth2Adapter(OAuth2Adapter): provider_id = "meetup" access_token_url = "https://secure.meetup.com/oauth2/access" authorize_url = "https://secure.meetup.com/oauth2/authorize" profile_url = "https://api.meetup.com/2/member/self" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(MeetupOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(MeetupOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/microsoft/000077500000000000000000000000001467545753200250235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/microsoft/__init__.py000066400000000000000000000000001467545753200271220ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/microsoft/provider.py000066400000000000000000000026521467545753200272340ustar00rootroot00000000000000from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.microsoft.views import ( MicrosoftGraphOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class MicrosoftGraphAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("photo") class MicrosoftGraphProvider(OAuth2Provider): id = "microsoft" name = "Microsoft" account_class = MicrosoftGraphAccount oauth2_adapter_class = MicrosoftGraphOAuth2Adapter def get_default_scope(self): """ Docs on Scopes and Permissions: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#scopes-and-permissions """ return ["User.Read"] def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["prompt"] = "select_account" return ret def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("mail") or data.get("userPrincipalName"), username=data.get("mailNickname"), last_name=data.get("surname"), first_name=data.get("givenName"), ) provider_classes = [MicrosoftGraphProvider] django-allauth-65.0.2/allauth/socialaccount/providers/microsoft/tests.py000066400000000000000000000040261467545753200265410ustar00rootroot00000000000000import json from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import MicrosoftGraphProvider from .views import _check_errors class MicrosoftGraphTests(OAuth2TestsMixin, TestCase): provider_id = MicrosoftGraphProvider.id def get_mocked_response(self): response_data = """ { "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity", "id": "16f5a7b6-5a15-4568-aa5a-31bb117e9967", "businessPhones": [], "displayName": "Anne Weiler", "givenName": "Anne", "jobTitle": "Manufacturing Lead", "mail": "annew@CIE493742.onmicrosoft.com", "mobilePhone": "+1 3528700812", "officeLocation": null, "preferredLanguage": "en-US", "surname": "Weiler", "userPrincipalName": "annew@CIE493742.onmicrosoft.com", "mailNickname": "annew" } """ # noqa return MockedResponse(200, response_data) def get_expected_to_str(self): return "annew@CIE493742.onmicrosoft.com" def test_invalid_data(self): response = MockedResponse(200, json.dumps({})) with self.assertRaises(OAuth2Error): # No id, raises _check_errors(response) def test_profile_invalid_response(self): data = { "error": { "code": "InvalidAuthenticationToken", "message": "Access token validation failure. Invalid audience.", } } response = MockedResponse(401, json.dumps(data)) with self.assertRaises(OAuth2Error): # no id, 4xx code, raises with message _check_errors(response) def test_invalid_response(self): response = MockedResponse(200, "invalid json data") with self.assertRaises(OAuth2Error): # bad json, raises _check_errors(response) django-allauth-65.0.2/allauth/socialaccount/providers/microsoft/urls.py000066400000000000000000000002661467545753200263660ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import MicrosoftGraphProvider urlpatterns = default_urlpatterns(MicrosoftGraphProvider) django-allauth-65.0.2/allauth/socialaccount/providers/microsoft/views.py000066400000000000000000000057231467545753200265410ustar00rootroot00000000000000import json from allauth.core import context from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) def _check_errors(response): try: data = response.json() except json.decoder.JSONDecodeError: raise OAuth2Error( "Invalid JSON from Microsoft Graph API: {}".format(response.text) ) if "id" not in data: error_message = "Error retrieving Microsoft profile" microsoft_error_message = data.get("error", {}).get("message") if microsoft_error_message: error_message = ": ".join((error_message, microsoft_error_message)) raise OAuth2Error(error_message) return data class MicrosoftGraphOAuth2Adapter(OAuth2Adapter): provider_id = "microsoft" def _build_tenant_url(self, path): settings = app_settings.PROVIDERS.get(self.provider_id, {}) # Lower case "tenant" for backwards compatibility tenant = settings.get("TENANT", settings.get("tenant", "common")) # Prefer app based tenant setting. app = get_adapter().get_app(context.request, provider=self.provider_id) tenant = app.settings.get("tenant", tenant) login_url = app.settings.get("login_url", "https://login.microsoftonline.com") return f"{login_url}/{tenant}{path}" @property def access_token_url(self): return self._build_tenant_url("/oauth2/v2.0/token") @property def authorize_url(self): return self._build_tenant_url("/oauth2/v2.0/authorize") @property def profile_url(self): app = get_adapter().get_app(context.request, provider=self.provider_id) graph_url = app.settings.get("graph_url", "https://graph.microsoft.com") return f"{graph_url}/v1.0/me" user_properties = ( "businessPhones", "displayName", "givenName", "id", "jobTitle", "mail", "mobilePhone", "officeLocation", "preferredLanguage", "surname", "userPrincipalName", "mailNickname", "companyName", ) profile_url_params = {"$select": ",".join(user_properties)} def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} response = ( get_adapter() .get_requests_session() .get( self.profile_url, params=self.profile_url_params, headers=headers, ) ) extra_data = _check_errors(response) return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(MicrosoftGraphOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(MicrosoftGraphOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/miro/000077500000000000000000000000001467545753200237645ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/miro/__init__.py000066400000000000000000000000001467545753200260630ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/miro/provider.py000066400000000000000000000017341467545753200261750ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.miro.views import MiroOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class MiroAccount(ProviderAccount): pass class MiroProvider(OAuth2Provider): id = "miro" name = "Miro" account_class = MiroAccount oauth2_adapter_class = MiroOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict(email=data.get("email"), name=data.get("name")) def get_default_scope(self): return ["identity:read"] def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("state") == "registered": ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [MiroProvider] django-allauth-65.0.2/allauth/socialaccount/providers/miro/tests.py000066400000000000000000000017161467545753200255050ustar00rootroot00000000000000from allauth.socialaccount.providers.miro.provider import MiroProvider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class MiroTests(OAuth2TestsMixin, TestCase): provider_id = MiroProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "type" : "user", "id" : "5298357290348572584", "name" : "Pavel Oborin", "createdAt" : "2017-03-23T09:41:01Z", "role" : "developer", "email" : "oborin.p@gmail.com", "state" : "registered", "picture" : { "type" : "picture", "id" : "Optional[5289752983457238457]", "imageUrl" : "https://r.miro.com/some/image" } }""", ) def get_expected_to_str(self): return "oborin.p@gmail.com" django-allauth-65.0.2/allauth/socialaccount/providers/miro/urls.py000066400000000000000000000003051467545753200253210ustar00rootroot00000000000000from allauth.socialaccount.providers.miro.provider import MiroProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(MiroProvider) django-allauth-65.0.2/allauth/socialaccount/providers/miro/views.py000066400000000000000000000017371467545753200255030ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class MiroOAuth2Adapter(OAuth2Adapter): provider_id = "miro" access_token_url = "https://api.miro.com/v1/oauth/token" authorize_url = "https://miro.com/oauth/authorize" profile_url = "https://api.miro.com/v1/users/me" def complete_login(self, request, app, token, response): headers = { "Authorization": f"Bearer {token.token}", "Content-Type": "application/json", } extra_data = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data.raise_for_status() return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth2_login = OAuth2LoginView.adapter_view(MiroOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(MiroOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/naver/000077500000000000000000000000001467545753200241315ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/naver/__init__.py000066400000000000000000000000001467545753200262300ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/naver/models.py000066400000000000000000000000001467545753200257540ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/naver/provider.py000066400000000000000000000017141467545753200263400ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.naver.views import NaverOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class NaverAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("profile_image") class NaverProvider(OAuth2Provider): id = "naver" name = "Naver" account_class = NaverAccount oauth2_adapter_class = NaverOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): email = data.get("email") return dict(email=email) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email: ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [NaverProvider] django-allauth-65.0.2/allauth/socialaccount/providers/naver/tests.py000066400000000000000000000014421467545753200256460ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import NaverProvider class NaverTests(OAuth2TestsMixin, TestCase): provider_id = NaverProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "response": { "enc_id": "46111c25f969116de4e545f13a415bb5383db2a79782da8851db72b2cced3180", "nickname": "\ubc31\ud638", "profile_image": "https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif", "gender": "M", "id": "7163491", "age": "20-29", "birthday": "03-22", "email": "shlee940322@example.com", "name": "\uc774\uc0c1\ud601" }, "message": "success", "resultcode": "00" } """, ) def get_expected_to_str(self): return "shlee940322@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/naver/urls.py000066400000000000000000000002441467545753200254700ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import NaverProvider urlpatterns = default_urlpatterns(NaverProvider) django-allauth-65.0.2/allauth/socialaccount/providers/naver/views.py000066400000000000000000000017171467545753200256460ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class NaverOAuth2Adapter(OAuth2Adapter): provider_id = "naver" access_token_url = "https://nid.naver.com/oauth2.0/token" authorize_url = "https://nid.naver.com/oauth2.0/authorize" profile_url = "https://openapi.naver.com/v1/nid/me" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json().get("response") return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(NaverOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(NaverOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/netiq/000077500000000000000000000000001467545753200241365ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/netiq/__init__.py000066400000000000000000000000001467545753200262350ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/netiq/provider.py000066400000000000000000000015461467545753200263500ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.netiq.views import NetIQOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class NetIQAccount(ProviderAccount): pass class NetIQProvider(OAuth2Provider): id = "netiq" name = "NetIQ" account_class = NetIQAccount oauth2_adapter_class = NetIQOAuth2Adapter def get_default_scope(self): return ["openid", "profile", "email"] def extract_uid(self, data): return str(data["preferred_username"]) def extract_extra_data(self, data): return data def extract_common_fields(self, data): return dict( email=data["email"], last_name=data["family_name"], first_name=data["given_name"], ) provider_classes = [NetIQProvider] django-allauth-65.0.2/allauth/socialaccount/providers/netiq/tests.py000066400000000000000000000016101467545753200256500ustar00rootroot00000000000000from allauth.socialaccount.providers.netiq.provider import NetIQProvider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class NetIQTests(OAuth2TestsMixin, TestCase): provider_id = NetIQProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "sub": "d4c094dd899ab0408fb9d4c094dd899a", "acr": "secure/name/password/uri", "preferred_username": "Mocktest", "email": "mocktest@your.netiq.server.example.com", "nickname": "Mocktest", "family_name": "test", "given_name": "Mock", "website": "https://www.exanple.com" } """, ) def get_expected_to_str(self): return "mocktest@your.netiq.server.example.com" django-allauth-65.0.2/allauth/socialaccount/providers/netiq/urls.py000066400000000000000000000003101467545753200254670ustar00rootroot00000000000000from allauth.socialaccount.providers.netiq.provider import NetIQProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(NetIQProvider) django-allauth-65.0.2/allauth/socialaccount/providers/netiq/views.py000066400000000000000000000031201467545753200256410ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class NetIQOAuth2Adapter(OAuth2Adapter): provider_id = "netiq" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("NETIQ_URL") @property def access_token_url(self): return "{}/nidp/oauth/nam/token".format(self.provider_base_url) @property def authorize_url(self): return "{}/nidp/oauth/nam/authz".format(self.provider_base_url) @property def userinfo_url(self): return "{}/nidp/oauth/nam/userinfo".format(self.provider_base_url) def complete_login(self, request, app, token, **kwargs): """ Get the user info from userinfo endpoint and return a A populated instance of the `SocialLogin` model (unsaved) :param request: :param app: :param token: :param kwargs: :return: """ resp = ( get_adapter() .get_requests_session() .get( self.userinfo_url, headers={"Authorization": "Bearer {}".format(token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() login = self.get_provider().sociallogin_from_response(request, extra_data) return login oauth2_login = OAuth2LoginView.adapter_view(NetIQOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(NetIQOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/nextcloud/000077500000000000000000000000001467545753200250235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/nextcloud/__init__.py000066400000000000000000000000001467545753200271220ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/nextcloud/provider.py000066400000000000000000000014321467545753200272270ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.nextcloud.views import ( NextCloudOAuth2Adapter, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class NextCloudAccount(ProviderAccount): pass class NextCloudProvider(OAuth2Provider): id = "nextcloud" name = "NextCloud" account_class = NextCloudAccount oauth2_adapter_class = NextCloudOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( username=data["displayname"], email=data["email"], ) def get_default_scope(self): scope = ["read"] return scope provider_classes = [NextCloudProvider] django-allauth-65.0.2/allauth/socialaccount/providers/nextcloud/tests.py000066400000000000000000000034271467545753200265450ustar00rootroot00000000000000from django.test.utils import override_settings from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import NextCloudProvider @override_settings( SOCIALACCOUNT_PROVIDERS={"nextcloud": {"SERVER": "https://nextcloud.example.org"}} ) class NextCloudTests(OAuth2TestsMixin, TestCase): provider_id = NextCloudProvider.id def get_login_response_json(self, with_refresh_token=True): return ( super(NextCloudTests, self) .get_login_response_json(with_refresh_token=with_refresh_token) .replace("uid", "user_id") ) def get_mocked_response(self): return MockedResponse( 200, """ ok 100 OK 1 batman /var/www/html/data/batman 1553946472000 Database 1455417655296 467191265 1455884846561 0.03 -3 batman@wayne.com batman 7351857301
BatCave, Gotham City
https://batman.org @the_batman admin fr fr_FR 1 1
""", ) def get_expected_to_str(self): return "batman@wayne.com" django-allauth-65.0.2/allauth/socialaccount/providers/nextcloud/urls.py000066400000000000000000000002541467545753200263630ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import NextCloudProvider urlpatterns = default_urlpatterns(NextCloudProvider) django-allauth-65.0.2/allauth/socialaccount/providers/nextcloud/views.py000066400000000000000000000036701467545753200265400ustar00rootroot00000000000000import xml.etree.ElementTree as ET from allauth.core import context from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class NextCloudOAuth2Adapter(OAuth2Adapter): provider_id = "nextcloud" def _build_server_url(self, path): settings = app_settings.PROVIDERS.get(self.provider_id, {}) server = settings.get("SERVER", "https://nextcloud.example.org") # Prefer app based setting. app = get_adapter().get_app(context.request, provider=self.provider_id) server = app.settings.get("server", server) ret = f"{server}{path}" return ret @property def access_token_url(self): return self._build_server_url("/apps/oauth2/api/v1/token") @property def authorize_url(self): return self._build_server_url("/apps/oauth2/authorize") @property def profile_url(self): return self._build_server_url("/ocs/v1.php/cloud/users/") def complete_login(self, request, app, token: SocialToken, **kwargs): extra_data = self.get_user_info(token, kwargs["response"]["user_id"]) return self.get_provider().sociallogin_from_response(request, extra_data) def get_user_info(self, token: SocialToken, user_id): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter() .get_requests_session() .get(self.profile_url + user_id, headers=headers) ) resp.raise_for_status() data = ET.fromstring(resp.content.decode())[1] return {d.tag: d.text.strip() for d in data if d.text is not None} oauth2_login = OAuth2LoginView.adapter_view(NextCloudOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(NextCloudOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/notion/000077500000000000000000000000001467545753200243245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/notion/__init__.py000066400000000000000000000000001467545753200264230ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/notion/client.py000066400000000000000000000030621467545753200261550ustar00rootroot00000000000000from requests.auth import HTTPBasicAuth from urllib.parse import parse_qsl from django.utils.http import urlencode from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) class NotionOAuth2Client(OAuth2Client): def get_redirect_url(self, authorization_url, scope, extra_params): scope = self.scope_delimiter.join(set(scope)) params = { "client_id": self.consumer_key, "scope": scope, "response_type": "code", "owner": "user", } if self.state: params["state"] = self.state return "%s?%s" % (authorization_url, urlencode(params)) def get_access_token(self, code, pkce_code_verifier=None): resp = ( get_adapter() .get_requests_session() .request( self.access_token_method, self.access_token_url, auth=HTTPBasicAuth(self.consumer_key, self.consumer_secret), json={"code": code, "grant_type": "authorization_code"}, headers=self.headers, ) ) access_token = None if resp.status_code in [200, 201]: try: access_token = resp.json() except ValueError: access_token = dict(parse_qsl(resp.text)) if not access_token or "access_token" not in access_token: raise OAuth2Error("Error retrieving access token: %s" % resp.content) return access_token django-allauth-65.0.2/allauth/socialaccount/providers/notion/provider.py000066400000000000000000000033221467545753200265300ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.notion.views import NotionOAuth2Adapter from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class NotionAccount(ProviderAccount): def get_user(self): return self.account.extra_data["owner"]["user"] def get_name(self): return self.get_user()["name"] def get_avatar_url(self): return self.get_user()["avatar_url"] def get_workspace_name(self): return self.account.extra_data["workspace_name"] def get_workspace_icon(self): return self.account.extra_data["workspace_icon"] def to_str(self): name = self.get_name() workspace = self.get_workspace_name() return f"{name} ({workspace})" class NotionProvider(OAuth2Provider): id = "notion" name = "Notion" account_class = NotionAccount oauth2_adapter_class = NotionOAuth2Adapter def extract_uid(self, data): """ The unique identifier for Notion is a combination of the User ID and the Workspace ID they have authorized the application with. """ user_id = data["owner"]["user"]["id"] workspace_id = data["workspace_id"] return "user-%s_workspace-%s" % (user_id, workspace_id) def extract_common_fields(self, data): user = data["owner"]["user"] user["email"] = user["person"]["email"] return user def extract_email_addresses(self, data): user = data["owner"]["user"] email = user["person"]["email"] return [EmailAddress(email=email, verified=True, primary=True)] provider_classes = [NotionProvider] django-allauth-65.0.2/allauth/socialaccount/providers/notion/tests.py000066400000000000000000000055261467545753200260500ustar00rootroot00000000000000from urllib.parse import parse_qs, urlparse from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .provider import NotionProvider class NotionTests(OAuth2TestsMixin, TestCase): provider_id = NotionProvider.id pkce_enabled_default = False # Notion does not support PKCE. def get_mocked_response(self): return MockedResponse( 200, """ { "workspace_id": "workspace-abc", "workspace_name": "My Workspace", "owner": { "user": { "id": "test123", "name": "John Doe", "avatar_url": "", "person": {"email": "john@example.com"}, } }, } """, ) # noqa def get_expected_to_str(self): return "John Doe (My Workspace)" def get_login_response_json(self, with_refresh_token=False): """ Docs here: https://developers.notion.com/docs/authorization#step-4-notion-responds-with-an-access_token-and-additional-information """ return """ { "access_token": "testac", "bot_id": "bot-abc", "duplicated_template_id": "template-abc", "owner": { "workspace_id": "workspace-abc", "user": { "id": "test123", "name": "John Doe", "avatar_url": "", "person": { "email": "john@example.com" } } }, "workspace_icon": "https://example.com/icon.png", "workspace_id": "workspace-abc", "workspace_name": "My Workspace" } """ def login(self, resp_mock=None, process="login", with_refresh_token=True): resp = self.client.post( reverse(self.provider.id + "_login") + "?" + urlencode(dict(process=process)) ) p = urlparse(resp["location"]) q = parse_qs(p.query) complete_url = reverse(self.provider.id + "_callback") response_json = self.get_login_response_json( with_refresh_token=with_refresh_token ) if isinstance(resp_mock, list): resp_mocks = resp_mock elif resp_mock is None: resp_mocks = [] else: resp_mocks = [resp_mock] with mocked_response( MockedResponse(200, response_json, {"content-type": "application/json"}), *resp_mocks, ): resp = self.client.get(complete_url, self.get_complete_parameters(q)) return resp django-allauth-65.0.2/allauth/socialaccount/providers/notion/urls.py000066400000000000000000000003131467545753200256600ustar00rootroot00000000000000from allauth.socialaccount.providers.notion.provider import NotionProvider from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns urlpatterns = default_urlpatterns(NotionProvider) django-allauth-65.0.2/allauth/socialaccount/providers/notion/views.py000066400000000000000000000013401467545753200260310ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .client import NotionOAuth2Client class NotionOAuth2Adapter(OAuth2Adapter): provider_id = "notion" basic_auth = True client_class = NotionOAuth2Client authorize_url = "https://api.notion.com/v1/oauth/authorize" access_token_url = "https://api.notion.com/v1/oauth/token" def complete_login(self, request, app, token, **kwargs): return self.get_provider().sociallogin_from_response( request, kwargs["response"] ) oauth2_login = OAuth2LoginView.adapter_view(NotionOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(NotionOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/oauth/000077500000000000000000000000001467545753200241365ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/oauth/__init__.py000066400000000000000000000000001467545753200262350ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/oauth/client.py000066400000000000000000000166401467545753200257750ustar00rootroot00000000000000""" Parts derived from socialregistration and authorized by: alen, pinda Inspired by: http://github.com/leah/python-oauth/blob/master/oauth/example/client.py http://github.com/facebook/tornado/blob/master/tornado/auth.py """ from urllib.parse import parse_qsl, urlparse from django.http import HttpResponseRedirect from django.utils.http import urlencode from django.utils.translation import gettext as _ from requests_oauthlib import OAuth1 from allauth.socialaccount.adapter import get_adapter from allauth.utils import build_absolute_uri, get_request_param def get_token_prefix(url): """ Returns a prefix for the token to store in the session so we can hold more than one single oauth provider's access key in the session. Example: The request token url ``http://twitter.com/oauth/request_token`` returns ``twitter.com`` """ return urlparse(url).netloc class OAuthError(Exception): pass class OAuthClient: def __init__( self, request, consumer_key, consumer_secret, request_token_url, access_token_url, callback_url, parameters=None, provider=None, ): self.request = request self.request_token_url = request_token_url self.access_token_url = access_token_url self.consumer_key = consumer_key self.consumer_secret = consumer_secret self.parameters = parameters self.callback_url = callback_url self.provider = provider self.errors = [] self.request_token = None self.access_token = None def _get_request_token(self): """ Obtain a temporary request token to authorize an access token and to sign the request to obtain the access token """ if self.request_token is None: get_params = {} if self.parameters: get_params.update(self.parameters) get_params["oauth_callback"] = build_absolute_uri( self.request, self.callback_url ) rt_url = self.request_token_url + "?" + urlencode(get_params) oauth = OAuth1(self.consumer_key, client_secret=self.consumer_secret) response = get_adapter().get_requests_session().post(url=rt_url, auth=oauth) if response.status_code not in [200, 201]: raise OAuthError( _( "Invalid response while obtaining request token" ' from "%s". Response was: %s.' ) % (get_token_prefix(self.request_token_url), response.text) ) self.request_token = dict(parse_qsl(response.text)) self.request.session[ "oauth_%s_request_token" % get_token_prefix(self.request_token_url) ] = self.request_token return self.request_token def get_access_token(self): """ Obtain the access token to access private resources at the API endpoint. """ if self.access_token is None: request_token = self._get_rt_from_session() oauth = OAuth1( self.consumer_key, client_secret=self.consumer_secret, resource_owner_key=request_token["oauth_token"], resource_owner_secret=request_token["oauth_token_secret"], ) at_url = self.access_token_url # Passing along oauth_verifier is required according to: # http://groups.google.com/group/twitter-development-talk/browse_frm/thread/472500cfe9e7cdb9# # Though, the custom oauth_callback seems to work without it? oauth_verifier = get_request_param(self.request, "oauth_verifier") if oauth_verifier: at_url = at_url + "?" + urlencode({"oauth_verifier": oauth_verifier}) response = get_adapter().get_requests_session().post(url=at_url, auth=oauth) if response.status_code not in [200, 201]: raise OAuthError( _("Invalid response while obtaining access token" ' from "%s".') % get_token_prefix(self.request_token_url) ) self.access_token = dict(parse_qsl(response.text)) self.request.session[ "oauth_%s_access_token" % get_token_prefix(self.request_token_url) ] = self.access_token return self.access_token def _get_rt_from_session(self): """ Returns the request token cached in the session by ``_get_request_token`` """ try: return self.request.session[ "oauth_%s_request_token" % get_token_prefix(self.request_token_url) ] except KeyError: raise OAuthError( _('No request token saved for "%s".') % get_token_prefix(self.request_token_url) ) def is_valid(self): try: self._get_rt_from_session() self.get_access_token() except OAuthError as e: self.errors.append(e.args[0]) return False return True def get_redirect(self, authorization_url, extra_params): """ Returns a ``HttpResponseRedirect`` object to redirect the user to the URL the OAuth provider handles authorization. """ request_token = self._get_request_token() params = { "oauth_token": request_token["oauth_token"], "oauth_callback": self.request.build_absolute_uri(self.callback_url), } params.update(extra_params) url = authorization_url + "?" + urlencode(params) return HttpResponseRedirect(url) class OAuth: """ Base class to perform oauth signed requests from access keys saved in a user's session. See the ``OAuthTwitter`` class below for an example. """ def __init__(self, request, consumer_key, secret_key, request_token_url): self.request = request self.consumer_key = consumer_key self.secret_key = secret_key self.request_token_url = request_token_url def _get_at_from_session(self): """ Get the saved access token for private resources from the session. """ try: return self.request.session[ "oauth_%s_access_token" % get_token_prefix(self.request_token_url) ] except KeyError: raise OAuthError( _('No access token saved for "%s".') % get_token_prefix(self.request_token_url) ) def query(self, url, method="GET", params=None, headers=None): """ Request a API endpoint at ``url`` with ``params`` being either the POST or GET data. """ access_token = self._get_at_from_session() oauth = OAuth1( self.consumer_key, client_secret=self.secret_key, resource_owner_key=access_token["oauth_token"], resource_owner_secret=access_token["oauth_token_secret"], ) response = getattr(get_adapter().get_requests_session(), method.lower())( url, auth=oauth, headers=headers, params=params ) if response.status_code != 200: raise OAuthError( _('No access to private resources at "%s".') % get_token_prefix(self.request_token_url) ) return response.text django-allauth-65.0.2/allauth/socialaccount/providers/oauth/provider.py000066400000000000000000000063741467545753200263540ustar00rootroot00000000000000import logging from urllib.parse import parse_qsl from django.core.exceptions import ImproperlyConfigured from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.helpers import render_authentication_error from allauth.socialaccount.providers.base import Provider from allauth.socialaccount.providers.base.constants import AuthAction from allauth.socialaccount.providers.oauth.client import OAuthError logger = logging.getLogger(__name__) class OAuthProvider(Provider): supports_redirect = True def get_login_url(self, request, **kwargs): url = reverse(self.id + "_login") if kwargs: url = url + "?" + urlencode(kwargs) return url def get_auth_params(self): settings = self.get_settings() ret = dict(settings.get("AUTH_PARAMS", {})) return ret def get_auth_params_from_request(self, request, action): ret = self.get_auth_params() dynamic_auth_params = request.GET.get("auth_params", None) if dynamic_auth_params: ret.update(dict(parse_qsl(dynamic_auth_params))) return ret def get_auth_url(self, request, action): # TODO: This is ugly. Move authorization_url away from the # adapter into the provider. Hmpf, the line between # adapter/provider is a bit too thin here. return None def get_scope_from_request(self, request): return self.get_scope() def get_scope(self): settings = self.get_settings() scope = settings.get("SCOPE") if scope is None: scope = self.get_default_scope() return scope def get_default_scope(self): return [] def get_oauth_adapter(self, request): if not hasattr(self, "oauth_adapter_class"): raise ImproperlyConfigured(f"No oauth_adapter_class set for {self!r}") return self.oauth_adapter_class(request) def get_redirect_from_request_kwargs(self, request): kwargs = super().get_redirect_from_request_kwargs(request) kwargs["scope"] = self.get_scope_from_request(request) action = request.GET.get("action", AuthAction.AUTHENTICATE) kwargs["action"] = action kwargs["auth_params"] = self.get_auth_params_from_request(request, action) return kwargs def redirect(self, request, process, next_url=None, data=None, **kwargs): callback_url = reverse(self.id + "_callback") oauth_adapter = self.get_oauth_adapter(request) action = kwargs.pop("action", AuthAction.AUTHENTICATE) auth_url = self.get_auth_url(request, action) or oauth_adapter.authorize_url auth_params = kwargs.pop("auth_params", None) if auth_params is None: auth_params = self.get_auth_params() scope = kwargs.pop("scope", None) if scope is None: scope = self.get_scope() self.stash_redirect_state(request, process, next_url, data, **kwargs) client = oauth_adapter._get_client(request, callback_url, scope=scope) try: return client.get_redirect(auth_url, auth_params) except OAuthError as e: logger.error("OAuth authentication error", exc_info=True) return render_authentication_error(request, self, exception=e) django-allauth-65.0.2/allauth/socialaccount/providers/oauth/urls.py000066400000000000000000000010171467545753200254740ustar00rootroot00000000000000from django.urls import include, path from allauth.utils import import_attribute def default_urlpatterns(provider): login_view = import_attribute(provider.get_package() + ".views.oauth_login") callback_view = import_attribute(provider.get_package() + ".views.oauth_callback") urlpatterns = [ path("login/", login_view, name=provider.id + "_login"), path("login/callback/", callback_view, name=provider.id + "_callback"), ] return [path(provider.get_slug() + "/", include(urlpatterns))] django-allauth-65.0.2/allauth/socialaccount/providers/oauth/views.py000066400000000000000000000072001467545753200256440ustar00rootroot00000000000000import logging from django.urls import reverse from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.models import SocialLogin, SocialToken from allauth.socialaccount.providers.base.constants import AuthError from allauth.socialaccount.providers.base.views import BaseLoginView from allauth.socialaccount.providers.oauth.client import ( OAuthClient, OAuthError, ) logger = logging.getLogger(__name__) class OAuthAdapter: client_class = OAuthClient def __init__(self, request): self.request = request def complete_login(self, request, app): """ Returns a SocialLogin instance """ raise NotImplementedError def get_provider(self): adapter = get_adapter(self.request) app = adapter.get_app(self.request, provider=self.provider_id) return app.get_provider(self.request) def _get_client(self, request, callback_url, scope=None): provider = self.get_provider() app = provider.app parameters = {} if scope: parameters["scope"] = " ".join(scope) client = self.client_class( request, app.client_id, app.secret, self.request_token_url, self.access_token_url, callback_url, parameters=parameters, provider=provider, ) return client class OAuthView: @classmethod def adapter_view(cls, adapter): @login_not_required def view(request, *args, **kwargs): self = cls() self.request = request self.adapter = adapter(request) return self.dispatch(request, *args, **kwargs) return view class OAuthLoginView(OAuthView, BaseLoginView): def get_provider(self): provider = self.adapter.get_provider() return provider class OAuthCallbackView(OAuthView): def dispatch(self, request): """ View to handle final steps of OAuth based authentication where the user gets redirected back to from the service provider """ provider = self.adapter.get_provider() login_done_url = reverse(self.adapter.provider_id + "_callback") client = self.adapter._get_client(request, login_done_url) if not client.is_valid(): if "denied" in request.GET: error = AuthError.CANCELLED else: error = AuthError.UNKNOWN return render_authentication_error( request, provider, error=error, extra_context={ "oauth_client": client, "callback_view": self, }, ) app = provider.app try: access_token = client.get_access_token() token = SocialToken( token=access_token["oauth_token"], # .get() -- e.g. Evernote does not feature a secret token_secret=access_token.get("oauth_token_secret", ""), ) if app.pk: token.app = app login = self.adapter.complete_login( request, app, token, response=access_token ) login.token = token login.state = SocialLogin.unstash_state(request) return complete_social_login(request, login) except OAuthError as e: return render_authentication_error(request, provider, exception=e) django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/000077500000000000000000000000001467545753200242205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/__init__.py000066400000000000000000000000001467545753200263170ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/client.py000066400000000000000000000066071467545753200260610ustar00rootroot00000000000000import requests from urllib.parse import parse_qsl from django.utils.http import urlencode from allauth.socialaccount.adapter import get_adapter class OAuth2Error(Exception): pass class OAuth2Client: client_id_parameter = "client_id" def __init__( self, request, consumer_key, consumer_secret, access_token_method, access_token_url, callback_url, scope_delimiter=" ", headers=None, basic_auth=False, ): self.request = request self.access_token_method = access_token_method self.access_token_url = access_token_url self.callback_url = callback_url self.consumer_key = consumer_key self.consumer_secret = consumer_secret self.scope_delimiter = scope_delimiter self.state = None self.headers = headers self.basic_auth = basic_auth def get_redirect_url(self, authorization_url, scope, extra_params): scope = self.scope_delimiter.join(set(scope)) params = { self.client_id_parameter: self.consumer_key, "redirect_uri": self.callback_url, "scope": scope, "response_type": "code", } if self.state: params["state"] = self.state params.update(extra_params) return "%s?%s" % (authorization_url, urlencode(params)) def get_access_token(self, code, pkce_code_verifier=None): data = { "redirect_uri": self.callback_url, "grant_type": "authorization_code", "code": code, } if self.basic_auth: auth = requests.auth.HTTPBasicAuth(self.consumer_key, self.consumer_secret) else: auth = None data.update( { self.client_id_parameter: self.consumer_key, "client_secret": self.consumer_secret, } ) params = None self._strip_empty_keys(data) url = self.access_token_url if self.access_token_method == "GET": params = data data = None if data and pkce_code_verifier: data["code_verifier"] = pkce_code_verifier # TODO: Proper exception handling resp = ( get_adapter() .get_requests_session() .request( self.access_token_method, url, params=params, data=data, headers=self.headers, auth=auth, ) ) access_token = None if resp.status_code in [200, 201]: # Weibo sends json via 'text/plain;charset=UTF-8' if ( resp.headers["content-type"].split(";")[0] == "application/json" or resp.text[:2] == '{"' ): access_token = resp.json() else: access_token = dict(parse_qsl(resp.text)) if not access_token or "access_token" not in access_token: raise OAuth2Error("Error retrieving access token: %s" % resp.content) return access_token def _strip_empty_keys(self, params): """Added because the Dropbox OAuth2 flow doesn't work when scope is passed in, which is empty. """ keys = [k for k, v in params.items() if v == ""] for key in keys: del params[key] django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/provider.py000066400000000000000000000110131467545753200264200ustar00rootroot00000000000000from typing import Type from urllib.parse import parse_qsl from django.core.exceptions import ImproperlyConfigured from django.http import HttpResponseRedirect from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.helpers import render_authentication_error from allauth.socialaccount.providers.base import Provider from allauth.socialaccount.providers.base.constants import AuthAction from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.utils import ( generate_code_challenge, ) from allauth.socialaccount.providers.oauth2.views import OAuth2Adapter class OAuth2Provider(Provider): pkce_enabled_default = False oauth2_adapter_class: Type[OAuth2Adapter] supports_redirect = True def get_login_url(self, request, **kwargs): url = reverse(self.id + "_login") if kwargs: url = url + "?" + urlencode(kwargs) return url def get_callback_url(self): return reverse(self.id + "_callback") def get_pkce_params(self): settings = self.get_settings() if settings.get("OAUTH_PKCE_ENABLED", self.pkce_enabled_default): pkce_code_params = generate_code_challenge() return pkce_code_params return {} def get_auth_params(self): """ Returns a dictionary of additional parameters passed to the OAuth2 redirect URL. Additional -- so no need to pass the standard `client_id`, `redirect_uri`, `response_type`. """ settings = self.get_settings() ret = dict(settings.get("AUTH_PARAMS", {})) return ret def get_auth_params_from_request(self, request, action): """ Returns a dictionary of additional parameters passed to the OAuth2 redirect URL. Additional -- so no need to pass the standard `client_id`, `redirect_uri`, `response_type`. """ ret = self.get_auth_params() dynamic_auth_params = request.GET.get("auth_params", None) if dynamic_auth_params: ret.update(dict(parse_qsl(dynamic_auth_params))) return ret def get_default_scope(self): """ Returns the default scope to use. """ return [] def get_scope(self): """ Returns the scope to use, taking settings `SCOPE` into consideration. """ settings = self.get_settings() scope = list(settings.get("SCOPE", self.get_default_scope())) return scope def get_scope_from_request(self, request): """ Returns the scope to use for the given request. """ scope = self.get_scope() dynamic_scope = request.GET.get("scope", None) if dynamic_scope: scope.extend(dynamic_scope.split(",")) return scope def get_oauth2_adapter(self, request): if not hasattr(self, "oauth2_adapter_class"): raise ImproperlyConfigured(f"No oauth2_adapter_class set for {self!r}") return self.oauth2_adapter_class(request) def get_redirect_from_request_kwargs(self, request): kwargs = super().get_redirect_from_request_kwargs(request) kwargs["scope"] = self.get_scope_from_request(request) action = request.GET.get("action", AuthAction.AUTHENTICATE) kwargs["auth_params"] = self.get_auth_params_from_request(request, action) return kwargs def redirect(self, request, process, next_url=None, data=None, **kwargs): app = self.app oauth2_adapter = self.get_oauth2_adapter(request) client = oauth2_adapter.get_client(request, app) auth_params = kwargs.pop("auth_params", None) if auth_params is None: auth_params = self.get_auth_params() pkce_params = self.get_pkce_params() code_verifier = pkce_params.pop("code_verifier", None) auth_params.update(pkce_params) scope = kwargs.pop("scope", None) if scope is None: scope = self.get_scope() state_id = self.stash_redirect_state( request, process, next_url, data, pkce_code_verifier=code_verifier, **kwargs ) client.state = state_id try: return HttpResponseRedirect( client.get_redirect_url( oauth2_adapter.authorize_url, scope, auth_params ) ) except OAuth2Error as e: return render_authentication_error( request, self, extra_context={"state_id": state_id}, exception=e ) django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/tests/000077500000000000000000000000001467545753200253625ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/tests/__init__.py000066400000000000000000000000001467545753200274610ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/tests/test_views.py000066400000000000000000000017301467545753200301310ustar00rootroot00000000000000from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed @pytest.mark.parametrize( "samesite_strict,did_already_redirect,expect_redirect", [ (True, False, True), (True, True, False), (False, False, False), ], ) def test_samesite_strict( client, samesite_strict, settings, google_provider_settings, did_already_redirect, expect_redirect, db, ): settings.SESSION_COOKIE_SAMESITE = "Strict" if samesite_strict else "Lax" query = "?state=123" resp = client.get( reverse("google_callback") + query + ("&_redir" if did_already_redirect else "") ) if expect_redirect: assertTemplateUsed(resp, "socialaccount/login_redirect.html") assert ( resp.context["redirect_to"] == reverse("google_callback") + query + "&_redir=" ) else: assertTemplateUsed(resp, "socialaccount/authentication_error.html") django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/urls.py000066400000000000000000000010211467545753200255510ustar00rootroot00000000000000from django.urls import include, path from allauth.utils import import_attribute def default_urlpatterns(provider): login_view = import_attribute(provider.get_package() + ".views.oauth2_login") callback_view = import_attribute(provider.get_package() + ".views.oauth2_callback") urlpatterns = [ path("login/", login_view, name=provider.id + "_login"), path("login/callback/", callback_view, name=provider.id + "_callback"), ] return [path(provider.get_slug() + "/", include(urlpatterns))] django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/utils.py000066400000000000000000000010561467545753200257340ustar00rootroot00000000000000import base64 import hashlib from secrets import token_urlsafe def generate_code_challenge(): # Create a code verifier with a length of 128 characters code_verifier = token_urlsafe(96) hashed_verifier = hashlib.sha256(code_verifier.encode("ascii")) code_challenge = base64.urlsafe_b64encode(hashed_verifier.digest()) code_challenge_without_padding = code_challenge.rstrip(b"=") return { "code_verifier": code_verifier, "code_challenge_method": "S256", "code_challenge": code_challenge_without_padding, } django-allauth-65.0.2/allauth/socialaccount/providers/oauth2/views.py000066400000000000000000000157631467545753200257430ustar00rootroot00000000000000from datetime import timedelta from requests import RequestException from typing import Dict, Optional from django.conf import settings from django.core.exceptions import PermissionDenied from django.shortcuts import render from django.urls import reverse from django.utils import timezone from allauth.account import app_settings as account_settings from allauth.account.internal.decorators import login_not_required from allauth.core.exceptions import ImmediateHttpResponse from allauth.core.internal.httpkit import add_query_params from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.internal import statekit from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.base import ProviderException from allauth.socialaccount.providers.base.constants import AuthError from allauth.socialaccount.providers.base.views import BaseLoginView from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) from allauth.utils import build_absolute_uri, get_request_param class OAuth2Adapter: expires_in_key = "expires_in" client_class = OAuth2Client supports_state = True redirect_uri_protocol: Optional[str] = None access_token_method = "POST" login_cancelled_error = "access_denied" scope_delimiter = " " basic_auth = False headers: Optional[Dict[str, str]] = None def __init__(self, request): self.request = request self.did_fetch_access_token = False def get_provider(self): return get_adapter(self.request).get_provider( self.request, provider=self.provider_id ) def complete_login(self, request, app, token: SocialToken, **kwargs): """ Returns a SocialLogin instance """ raise NotImplementedError def get_callback_url(self, request, app): callback_url = reverse(self.provider_id + "_callback") protocol = self.redirect_uri_protocol return build_absolute_uri(request, callback_url, protocol) def parse_token(self, data): token = SocialToken(token=data["access_token"]) token.token_secret = data.get("refresh_token", "") expires_in = data.get(self.expires_in_key, None) if expires_in: token.expires_at = timezone.now() + timedelta(seconds=int(expires_in)) return token def get_access_token_data(self, request, app, client, pkce_code_verifier=None): code = get_request_param(self.request, "code") data = client.get_access_token(code, pkce_code_verifier=pkce_code_verifier) self.did_fetch_access_token = True return data def get_client(self, request, app): callback_url = self.get_callback_url(request, app) client = self.client_class( self.request, app.client_id, app.secret, self.access_token_method, self.access_token_url, callback_url, scope_delimiter=self.scope_delimiter, headers=self.headers, basic_auth=self.basic_auth, ) return client class OAuth2View: @classmethod def adapter_view(cls, adapter): @login_not_required def view(request, *args, **kwargs): self = cls() self.request = request if not isinstance(adapter, OAuth2Adapter): self.adapter = adapter(request) else: self.adapter = adapter try: return self.dispatch(request, *args, **kwargs) except ImmediateHttpResponse as e: return e.response return view class OAuth2LoginView(OAuth2View, BaseLoginView): def get_provider(self): return self.adapter.get_provider() class OAuth2CallbackView(OAuth2View): def dispatch(self, request, *args, **kwargs): provider = self.adapter.get_provider() state, resp = self._get_state(request, provider) if resp: return resp if "error" in request.GET or "code" not in request.GET: # Distinguish cancel from error auth_error = request.GET.get("error", None) if auth_error == self.adapter.login_cancelled_error: error = AuthError.CANCELLED else: error = AuthError.UNKNOWN return render_authentication_error( request, provider, error=error, extra_context={ "state": state, "callback_view": self, }, ) app = provider.app client = self.adapter.get_client(self.request, app) try: access_token = self.adapter.get_access_token_data( request, app, client, pkce_code_verifier=state.get("pkce_code_verifier") ) token = self.adapter.parse_token(access_token) if app.pk: token.app = app login = self.adapter.complete_login( request, app, token, response=access_token ) login.token = token login.state = state return complete_social_login(request, login) except ( PermissionDenied, OAuth2Error, RequestException, ProviderException, ) as e: return render_authentication_error( request, provider, exception=e, extra_context={"state": state} ) def _redirect_strict_samesite(self, request, provider): if ( "_redir" in request.GET or settings.SESSION_COOKIE_SAMESITE.lower() != "strict" or request.method != "GET" ): return redirect_to = request.get_full_path() redirect_to = add_query_params(redirect_to, {"_redir": ""}) return render( request, "socialaccount/login_redirect." + account_settings.TEMPLATE_EXTENSION, { "provider": provider, "redirect_to": redirect_to, }, ) def _get_state(self, request, provider): state = None state_id = get_request_param(request, "state") if self.adapter.supports_state: if state_id: state = statekit.unstash_state(request, state_id) else: state = statekit.unstash_last_state(request) if state is None: resp = self._redirect_strict_samesite(request, provider) if resp: # 'Strict' is in effect, let's try a redirect and then another # shot at finding our state... return None, resp return None, render_authentication_error( request, provider, extra_context={ "state_id": state_id, "callback_view": self, }, ) return state, None django-allauth-65.0.2/allauth/socialaccount/providers/odnoklassniki/000077500000000000000000000000001467545753200256665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/odnoklassniki/__init__.py000066400000000000000000000000001467545753200277650ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/odnoklassniki/provider.py000066400000000000000000000025171467545753200300770ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.odnoklassniki.views import ( OdnoklassnikiOAuth2Adapter, ) class OdnoklassnikiAccount(ProviderAccount): def get_profile_url(self): return "https://ok.ru/profile/" + self.account.extra_data["uid"] def get_avatar_url(self): ret = None pic_big_url = self.account.extra_data.get("pic1024x768") pic_medium_url = self.account.extra_data.get("pic640x480") pic_small_url = self.account.extra_data.get("pic190x190") if pic_big_url: return pic_big_url elif pic_medium_url: return pic_medium_url elif pic_small_url: return pic_small_url else: return ret class OdnoklassnikiProvider(OAuth2Provider): id = "odnoklassniki" name = "Odnoklassniki" account_class = OdnoklassnikiAccount oauth2_adapter_class = OdnoklassnikiOAuth2Adapter def extract_uid(self, data): return data["uid"] def extract_common_fields(self, data): return dict( last_name=data.get("last_name"), first_name=data.get("first_name"), email=data.get("email"), ) provider_classes = [OdnoklassnikiProvider] django-allauth-65.0.2/allauth/socialaccount/providers/odnoklassniki/tests.py000066400000000000000000000016761467545753200274140ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import OdnoklassnikiProvider class OdnoklassnikiTests(OAuth2TestsMixin, TestCase): provider_id = OdnoklassnikiProvider.id def get_mocked_response(self, verified_email=True): return MockedResponse( 200, """ {"uid":"561999209121","birthday":"1999-09-09","age":33,"first_name":"Ivan", "last_name":"Petrov","name":"Ivan Petrov","locale":"en","gender":"male", "has_email":true,"location":{"city":"Moscow","country":"RUSSIAN_FEDERATION", "countryCode":"RU","countryName":"Russia"},"online":"web","pic_1": "http://i500.mycdn.me/res/stub_50x50.gif", "pic_2":"http://usd1.mycdn.me/res/stub_128x96.gif"} """, ) def get_expected_to_str(self): return "Ivan Petrov" def get_login_response_json(self, with_refresh_token=True): return '{"access_token": "testac"}' # noqa django-allauth-65.0.2/allauth/socialaccount/providers/odnoklassniki/urls.py000066400000000000000000000002641467545753200272270ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import OdnoklassnikiProvider urlpatterns = default_urlpatterns(OdnoklassnikiProvider) django-allauth-65.0.2/allauth/socialaccount/providers/odnoklassniki/views.py000066400000000000000000000036421467545753200274020ustar00rootroot00000000000000from hashlib import md5 from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) USER_FIELDS = [ "age", "birthday", "current_status", "current_status_date", "current_status_id", "email", "first_name", "gender", "has_email", "last_name", "locale", "location", "name", "online", "photo_id", "pic1024x768", # big "pic190x190", # small "pic640x480", # medium "pic_1", # aka pic50x50 "pic_2", # aka pic128max "uid", ] class OdnoklassnikiOAuth2Adapter(OAuth2Adapter): provider_id = "odnoklassniki" access_token_url = "https://api.odnoklassniki.ru/oauth/token.do" authorize_url = "https://www.odnoklassniki.ru/oauth/authorize" profile_url = "https://api.odnoklassniki.ru/fb.do" access_token_method = "POST" def complete_login(self, request, app, token, **kwargs): data = { "method": "users.getCurrentUser", "access_token": token.token, "fields": ",".join(USER_FIELDS), "format": "JSON", "application_key": app.key, } suffix = md5( "{0:s}{1:s}".format(data["access_token"], app.secret).encode("utf-8") ).hexdigest() check_list = sorted( ["{0:s}={1:s}".format(k, v) for k, v in data.items() if k != "access_token"] ) data["sig"] = md5(("".join(check_list) + suffix).encode("utf-8")).hexdigest() response = ( get_adapter().get_requests_session().get(self.profile_url, params=data) ) extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(OdnoklassnikiOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(OdnoklassnikiOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/okta/000077500000000000000000000000001467545753200237545ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/okta/__init__.py000066400000000000000000000000001467545753200260530ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/okta/provider.py000066400000000000000000000024311467545753200261600ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.okta.views import OktaOAuth2Adapter class OktaAccount(ProviderAccount): pass class OktaProvider(OAuth2Provider): id = "okta" name = "Okta" account_class = OktaAccount oauth2_adapter_class = OktaOAuth2Adapter def get_default_scope(self): return ["openid", "profile", "email", "offline_access"] def extract_uid(self, data): return str(data["preferred_username"]) def extract_extra_data(self, data): return data def extract_email_addresses(self, data): return [ EmailAddress( email=data["email"], verified=bool(data["email_verified"]), primary=True ) ] def extract_common_fields(self, data): ret = dict( email=data["email"], last_name=data["family_name"], first_name=data["given_name"], ) preferred_username = data.get("preferred_username") if preferred_username: ret["username"] = preferred_username.partition("@")[0] return ret provider_classes = [OktaProvider] django-allauth-65.0.2/allauth/socialaccount/providers/okta/tests.py000066400000000000000000000016311467545753200254710ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import OktaProvider class OktaTests(OAuth2TestsMixin, TestCase): provider_id = OktaProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "sub": "00u33ow83pjQpCQJr1j8", "name": "Jon Smith", "locale": "AE", "email": "jsmith@example.com", "nickname": "Jon Smith", "preferred_username": "jsmith@example.com", "given_name": "Jon", "family_name": "Smith", "zoneinfo": "America/Los_Angeles", "updated_at": 1601285210, "email_verified": true } """, ) def get_expected_to_str(self): return "jsmith@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/okta/urls.py000066400000000000000000000002421467545753200253110ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import OktaProvider urlpatterns = default_urlpatterns(OktaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/okta/views.py000066400000000000000000000032271467545753200254670ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class OktaOAuth2Adapter(OAuth2Adapter): provider_id = "okta" settings = app_settings.PROVIDERS.get(provider_id, {}) okta_base_url = settings.get("OKTA_BASE_URL") @property def access_token_url(self): return "https://{}/oauth2/v1/token".format(self.okta_base_url) @property def authorize_url(self): return "https://{}/oauth2/v1/authorize".format(self.okta_base_url) @property def userinfo_url(self): return "https://{}/oauth2/v1/userinfo".format(self.okta_base_url) @property def access_token_method(self): return "POST" def complete_login(self, request, app, token, **kwargs): """ Get the user info from userinfo endpoint and return a A populated instance of the `SocialLogin` model (unsaved) :param request: :param app: :param token: :param kwargs: :return: """ resp = ( get_adapter() .get_requests_session() .get( self.userinfo_url, headers={"Authorization": "Bearer {}".format(token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() login = self.get_provider().sociallogin_from_response(request, extra_data) return login oauth2_login = OAuth2LoginView.adapter_view(OktaOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(OktaOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/openid/000077500000000000000000000000001467545753200242745ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openid/__init__.py000066400000000000000000000000001467545753200263730ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openid/admin.py000066400000000000000000000004411467545753200257350ustar00rootroot00000000000000from django.contrib import admin from .models import OpenIDNonce, OpenIDStore class OpenIDStoreAdmin(admin.ModelAdmin): pass class OpenIDNonceAdmin(admin.ModelAdmin): pass admin.site.register(OpenIDStore, OpenIDStoreAdmin) admin.site.register(OpenIDNonce, OpenIDNonceAdmin) django-allauth-65.0.2/allauth/socialaccount/providers/openid/forms.py000066400000000000000000000006411467545753200257750ustar00rootroot00000000000000from django import forms from django.utils.safestring import mark_safe class LoginForm(forms.Form): openid = forms.URLField( label=("OpenID"), help_text=mark_safe( 'Get an OpenID' ), ) next = forms.CharField(widget=forms.HiddenInput, required=False) process = forms.CharField(widget=forms.HiddenInput, required=False) django-allauth-65.0.2/allauth/socialaccount/providers/openid/migrations/000077500000000000000000000000001467545753200264505ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openid/migrations/0001_initial.py000066400000000000000000000031531467545753200311150ustar00rootroot00000000000000from django.db import migrations, models class Migration(migrations.Migration): dependencies = [] operations = [ migrations.CreateModel( name="OpenIDNonce", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ("server_url", models.CharField(max_length=255)), ("timestamp", models.IntegerField()), ("salt", models.CharField(max_length=255)), ("date_created", models.DateTimeField(auto_now_add=True)), ], options={}, bases=(models.Model,), ), migrations.CreateModel( name="OpenIDStore", fields=[ ( "id", models.AutoField( verbose_name="ID", serialize=False, auto_created=True, primary_key=True, ), ), ("server_url", models.CharField(max_length=255)), ("handle", models.CharField(max_length=255)), ("secret", models.TextField()), ("issued", models.IntegerField()), ("lifetime", models.IntegerField()), ("assoc_type", models.TextField()), ], options={}, bases=(models.Model,), ), ] django-allauth-65.0.2/allauth/socialaccount/providers/openid/migrations/__init__.py000066400000000000000000000000001467545753200305470ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openid/models.py000066400000000000000000000011741467545753200261340ustar00rootroot00000000000000from django.db import models class OpenIDStore(models.Model): server_url = models.CharField(max_length=255) handle = models.CharField(max_length=255) secret = models.TextField() issued = models.IntegerField() lifetime = models.IntegerField() assoc_type = models.TextField() def __str__(self): return self.server_url class OpenIDNonce(models.Model): server_url = models.CharField(max_length=255) timestamp = models.IntegerField() salt = models.CharField(max_length=255) date_created = models.DateTimeField(auto_now_add=True) def __str__(self): return self.server_url django-allauth-65.0.2/allauth/socialaccount/providers/openid/provider.py000066400000000000000000000056261467545753200265110ustar00rootroot00000000000000from urllib.parse import urlparse from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.providers.base import Provider, ProviderAccount from .utils import ( AXAttribute, OldAXAttribute, SRegField, get_email_from_response, get_value_from_response, ) class OpenIDAccount(ProviderAccount): def get_brand(self): ret = super(OpenIDAccount, self).get_brand() domain = urlparse(self.account.uid).netloc provider_map = {} for d, p in provider_map.items(): if domain.lower().find(d) >= 0: ret = p break return ret def to_str(self): return self.account.uid class OpenIDProvider(Provider): id = "openid" name = "OpenID" account_class = OpenIDAccount uses_apps = False def get_login_url(self, request, **kwargs): url = reverse("openid_login") if kwargs: url += "?" + urlencode(kwargs) return url def get_brands(self): default_servers = [] return self.get_settings().get("SERVERS", default_servers) def get_server_settings(self, endpoint): servers = self.get_settings().get("SERVERS", []) for server in servers: if endpoint is not None and endpoint.startswith(server.get("openid_url")): return server return {} def extract_extra_data(self, response): extra_data = {} server_settings = self.get_server_settings(response.endpoint.server_url) extra_attributes = server_settings.get("extra_attributes", []) for attribute_id, name, _ in extra_attributes: extra_data[attribute_id] = get_value_from_response( response, ax_names=[name] ) return extra_data def extract_uid(self, response): return response.identity_url def extract_common_fields(self, response): first_name = ( get_value_from_response( response, ax_names=[ AXAttribute.PERSON_FIRST_NAME, OldAXAttribute.PERSON_FIRST_NAME, ], ) or "" ) last_name = ( get_value_from_response( response, ax_names=[ AXAttribute.PERSON_LAST_NAME, OldAXAttribute.PERSON_LAST_NAME, ], ) or "" ) name = ( get_value_from_response( response, sreg_names=[SRegField.NAME], ax_names=[AXAttribute.PERSON_NAME, OldAXAttribute.PERSON_NAME], ) or "" ) return dict( email=get_email_from_response(response), first_name=first_name, last_name=last_name, name=name, ) provider_classes = [OpenIDProvider] django-allauth-65.0.2/allauth/socialaccount/providers/openid/tests.py000066400000000000000000000130401467545753200260060ustar00rootroot00000000000000from unittest.mock import Mock, patch from django.contrib.auth import get_user_model from django.test import override_settings from django.urls import reverse from openid.consumer import consumer from allauth.socialaccount.models import SocialAccount from allauth.tests import TestCase from . import views from .utils import AXAttribute class OpenIDTests(TestCase): def test_discovery_failure(self): """ This used to generate a server 500: DiscoveryFailure: No usable OpenID services found for http://www.google.com/ """ resp = self.client.post( reverse("openid_login"), dict(openid="http://www.google.com") ) self.assertTrue("openid" in resp.context["form"].errors) def test_login(self): # Location: https://s.yimg.com/wm/mbr/html/openid-eol-0.0.1.html resp = self.client.post( reverse(views.login), dict(openid="https://steamcommunity.com/openid") ) assert "steamcommunity.com/openid/login" in resp["location"] with patch( "allauth.socialaccount.providers.openid.views._openid_consumer" ) as consumer_mock: client = Mock() complete = Mock() consumer_mock.return_value = client client.complete = complete complete_response = Mock() complete.return_value = complete_response complete_response.status = consumer.SUCCESS complete_response.identity_url = "http://dummy/john/" with patch( "allauth.socialaccount.providers.openid.utils.SRegResponse" ) as sr_mock: with patch( "allauth.socialaccount.providers.openid.utils.FetchResponse" ) as fr_mock: sreg_mock = Mock() ax_mock = Mock() sr_mock.fromSuccessResponse = sreg_mock fr_mock.fromSuccessResponse = ax_mock sreg_mock.return_value = {} ax_mock.return_value = {AXAttribute.PERSON_FIRST_NAME: ["raymond"]} resp = self.client.post(reverse("openid_callback")) self.assertRedirects( resp, "/accounts/profile/", fetch_redirect_response=False, ) get_user_model().objects.get(first_name="raymond") social_account = SocialAccount.objects.get( uid=complete_response.identity_url ) account = social_account.get_provider_account() self.assertEqual(account.to_str(), complete_response.identity_url) @override_settings( SOCIALACCOUNT_PROVIDERS={ "openid": { "SERVERS": [ dict( id="yahoo", name="Yahoo", openid_url="http://me.yahoo.com", extra_attributes=[ ( "phone", "http://axschema.org/contact/phone/default", True, ) ], ) ] } } ) def test_login_with_extra_attributes(self): with patch("allauth.socialaccount.providers.openid.views.QUERY_EMAIL", True): resp = self.client.post( reverse(views.login), dict(openid="https://steamcommunity.com/openid") ) assert "steamcommunity.com/openid/login" in resp["location"] with patch( "allauth.socialaccount.providers.openid.views._openid_consumer" ) as consumer_mock: client = Mock() complete = Mock() endpoint = Mock() consumer_mock.return_value = client client.complete = complete complete_response = Mock() complete.return_value = complete_response complete_response.endpoint = endpoint complete_response.endpoint.server_url = "http://me.yahoo.com" complete_response.status = consumer.SUCCESS complete_response.identity_url = "http://dummy/john/" with patch( "allauth.socialaccount.providers.openid.utils.SRegResponse" ) as sr_mock: with patch( "allauth.socialaccount.providers.openid.utils.FetchResponse" ) as fr_mock: sreg_mock = Mock() ax_mock = Mock() sr_mock.fromSuccessResponse = sreg_mock fr_mock.fromSuccessResponse = ax_mock sreg_mock.return_value = {} ax_mock.return_value = { AXAttribute.CONTACT_EMAIL: ["raymond@example.com"], AXAttribute.PERSON_FIRST_NAME: ["raymond"], "http://axschema.org/contact/phone/default": ["123456789"], } resp = self.client.post(reverse("openid_callback")) self.assertRedirects( resp, "/accounts/profile/", fetch_redirect_response=False, ) socialaccount = SocialAccount.objects.get( user__first_name="raymond" ) self.assertEqual(socialaccount.extra_data.get("phone"), "123456789") django-allauth-65.0.2/allauth/socialaccount/providers/openid/urls.py000066400000000000000000000003111467545753200256260ustar00rootroot00000000000000from django.urls import path from . import views urlpatterns = [ path("openid/login/", views.login, name="openid_login"), path("openid/callback/", views.callback, name="openid_callback"), ] django-allauth-65.0.2/allauth/socialaccount/providers/openid/utils.py000066400000000000000000000124401467545753200260070ustar00rootroot00000000000000import base64 import pickle from collections import UserDict from openid.association import Association as OIDAssociation from openid.extensions.ax import FetchResponse from openid.extensions.sreg import SRegResponse from openid.store.interface import OpenIDStore as OIDStore from allauth.utils import valid_email_or_none from .models import OpenIDNonce, OpenIDStore class JSONSafeSession(UserDict): """ openid puts e.g. class OpenIDServiceEndpoint in the session. Django 1.6 no longer pickles stuff, so we'll need to do some hacking here... """ def __init__(self, session): UserDict.__init__(self) self.data = session def __setitem__(self, key, value): data = base64.b64encode(pickle.dumps(value)).decode("ascii") return UserDict.__setitem__(self, key, data) def __getitem__(self, key): data = UserDict.__getitem__(self, key) return pickle.loads(base64.b64decode(data.encode("ascii"))) class OldAXAttribute: PERSON_NAME = "http://openid.net/schema/namePerson" PERSON_FIRST_NAME = "http://openid.net/schema/namePerson/first" PERSON_LAST_NAME = "http://openid.net/schema/namePerson/last" class AXAttribute: CONTACT_EMAIL = "http://axschema.org/contact/email" PERSON_NAME = "http://axschema.org/namePerson" PERSON_FIRST_NAME = "http://axschema.org/namePerson/first" PERSON_LAST_NAME = "http://axschema.org/namePerson/last" AXAttributes = [ AXAttribute.CONTACT_EMAIL, AXAttribute.PERSON_NAME, AXAttribute.PERSON_FIRST_NAME, AXAttribute.PERSON_LAST_NAME, OldAXAttribute.PERSON_NAME, OldAXAttribute.PERSON_FIRST_NAME, OldAXAttribute.PERSON_LAST_NAME, ] class SRegField: EMAIL = "email" NAME = "fullname" SRegFields = [ SRegField.EMAIL, SRegField.NAME, ] class DBOpenIDStore(OIDStore): max_nonce_age = 6 * 60 * 60 def storeAssociation(self, server_url, assoc=None): try: secret = base64.encodebytes(assoc.secret) except AttributeError: # Python 2.x compat secret = base64.encodestring(assoc.secret) else: secret = secret.decode() OpenIDStore.objects.create( server_url=server_url, handle=assoc.handle, secret=secret, issued=assoc.issued, lifetime=assoc.lifetime, assoc_type=assoc.assoc_type, ) def getAssociation(self, server_url, handle=None): stored_assocs = OpenIDStore.objects.filter(server_url=server_url) if handle: stored_assocs = stored_assocs.filter(handle=handle) stored_assocs.order_by("-issued") if not stored_assocs.exists(): return None return_val = None for stored_assoc in stored_assocs: assoc = OIDAssociation( stored_assoc.handle, base64.decodebytes(stored_assoc.secret.encode("utf-8")), stored_assoc.issued, stored_assoc.lifetime, stored_assoc.assoc_type, ) # See: # necaris/python3-openid@1abb155c8fc7b508241cbe9d2cae24f18e4a379b if hasattr(assoc, "getExpiresIn"): expires_in = assoc.getExpiresIn() else: expires_in = assoc.expiresIn if expires_in == 0: stored_assoc.delete() else: if return_val is None: return_val = assoc return return_val def removeAssociation(self, server_url, handle): stored_assocs = OpenIDStore.objects.filter(server_url=server_url) if handle: stored_assocs = stored_assocs.filter(handle=handle) stored_assocs.delete() def useNonce(self, server_url, timestamp, salt): try: OpenIDNonce.objects.get( server_url=server_url, timestamp=timestamp, salt=salt ) except OpenIDNonce.DoesNotExist: OpenIDNonce.objects.create( server_url=server_url, timestamp=timestamp, salt=salt ) return True return False def get_email_from_response(response): email = None sreg = SRegResponse.fromSuccessResponse(response) if sreg: email = valid_email_or_none(sreg.get(SRegField.EMAIL)) if not email: ax = FetchResponse.fromSuccessResponse(response) if ax: try: values = ax.get(AXAttribute.CONTACT_EMAIL) if values: email = valid_email_or_none(values[0]) except KeyError: pass return email def get_value_from_response(response, sreg_names=None, ax_names=None): value = None if sreg_names: sreg = SRegResponse.fromSuccessResponse(response) if sreg: for name in sreg_names: value = sreg.get(name) if value: break if not value and ax_names: ax = FetchResponse.fromSuccessResponse(response) if ax: for name in ax_names: try: values = ax.get(name) if values: value = values[0] except KeyError: pass if value: break return value django-allauth-65.0.2/allauth/socialaccount/providers/openid/views.py000066400000000000000000000137361467545753200260150ustar00rootroot00000000000000from django.contrib.auth import REDIRECT_FIELD_NAME from django.http import HttpResponseRedirect from django.shortcuts import render from django.urls import reverse from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.csrf import csrf_exempt from openid.consumer import consumer from openid.consumer.discover import DiscoveryFailure from openid.extensions.ax import AttrInfo, FetchRequest from openid.extensions.sreg import SRegRequest from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.models import SocialLogin from ..base import AuthError from .forms import LoginForm from .provider import OpenIDProvider from .utils import AXAttributes, DBOpenIDStore, JSONSafeSession, SRegFields def _openid_consumer(request, provider, endpoint): server_settings = provider.get_server_settings(endpoint) stateless = server_settings.get("stateless", False) store = None if stateless else DBOpenIDStore() client = consumer.Consumer(JSONSafeSession(request.session), store) return client @method_decorator(login_not_required, name="dispatch") class OpenIDLoginView(View): template_name = "openid/login.html" form_class = LoginForm provider_class = OpenIDProvider def dispatch(self, request, *args, **kwargs): self.provider = self.provider_class(request) return super().dispatch(request, *args, **kwargs) def get(self, request): form = self.get_form() if not form.is_valid(): return render(request, self.template_name, {"form": form}) try: return self.perform_openid_auth(form) except (UnicodeDecodeError, DiscoveryFailure) as e: # UnicodeDecodeError: necaris/python3-openid#1 return render_authentication_error(request, self.provider, exception=e) def post(self, request): form = self.get_form() if form.is_valid(): try: return self.perform_openid_auth(form) except (UnicodeDecodeError, DiscoveryFailure) as e: form._errors["openid"] = form.error_class([e]) return render(request, self.template_name, {"form": form}) def get_form(self): if self.request.method == "GET" and "openid" not in self.request.GET: return self.form_class( initial={ "next": self.request.GET.get(REDIRECT_FIELD_NAME), "process": self.request.GET.get("process"), } ) return self.form_class( dict(list(self.request.GET.items()) + list(self.request.POST.items())) ) def get_client(self, provider, endpoint): return _openid_consumer(self.request, provider, endpoint) def get_realm(self, provider): return provider.get_settings().get( "REALM", self.request.build_absolute_uri("/") ) def get_callback_url(self): return reverse(callback) def perform_openid_auth(self, form): if not form.is_valid(): return form request = self.request provider = self.provider endpoint = form.cleaned_data["openid"] client = self.get_client(provider, endpoint) realm = self.get_realm(provider) auth_request = client.begin(endpoint) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) server_settings = provider.get_server_settings(request.GET.get("openid")) extra_attributes = server_settings.get("extra_attributes", []) for _, name, required in extra_attributes: ax.add(AttrInfo(name, required=required)) auth_request.addExtension(ax) SocialLogin.stash_state(request) # Fix for issues 1523 and 2072 (github django-allauth) if "next" in form.cleaned_data and form.cleaned_data["next"]: auth_request.return_to_args["next"] = form.cleaned_data["next"] redirect_url = auth_request.redirectURL( realm, request.build_absolute_uri(self.get_callback_url()) ) return HttpResponseRedirect(redirect_url) login = OpenIDLoginView.as_view() @method_decorator(login_not_required, name="dispatch") class OpenIDCallbackView(View): provider_class = OpenIDProvider def get(self, request): provider = self.provider = self.provider_class(request) endpoint = request.GET.get("openid.op_endpoint", "") client = self.get_client(provider, endpoint) response = self.get_openid_response(client) if response.status == consumer.SUCCESS: login = provider.sociallogin_from_response(request, response) login.state = SocialLogin.unstash_state(request) return self.complete_login(login) else: if response.status == consumer.CANCEL: error = AuthError.CANCELLED else: error = AuthError.UNKNOWN return self.render_error(error) post = get def complete_login(self, login): return complete_social_login(self.request, login) def render_error(self, error): return render_authentication_error(self.request, self.provider, error=error) def get_client(self, provider, endpoint): return _openid_consumer(self.request, provider, endpoint) def get_openid_response(self, client): return client.complete( dict(list(self.request.GET.items()) + list(self.request.POST.items())), self.request.build_absolute_uri(self.request.path), ) callback = csrf_exempt(OpenIDCallbackView.as_view()) django-allauth-65.0.2/allauth/socialaccount/providers/openid_connect/000077500000000000000000000000001467545753200260055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openid_connect/__init__.py000066400000000000000000000000001467545753200301040ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openid_connect/provider.py000066400000000000000000000051331467545753200302130ustar00rootroot00000000000000from django.urls import reverse from django.utils.http import urlencode from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.openid_connect.views import ( OpenIDConnectOAuth2Adapter, ) class OpenIDConnectProviderAccount(ProviderAccount): pass class OpenIDConnectProvider(OAuth2Provider): id = "openid_connect" name = "OpenID Connect" account_class = OpenIDConnectProviderAccount oauth2_adapter_class = OpenIDConnectOAuth2Adapter def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.name = self.app.name @property def server_url(self): url = self.app.settings["server_url"] return self.wk_server_url(url) def wk_server_url(self, url): well_known_uri = "/.well-known/openid-configuration" if not url.endswith(well_known_uri): url += well_known_uri return url def get_login_url(self, request, **kwargs): url = reverse( self.app.provider + "_login", kwargs={"provider_id": self.app.provider_id} ) if kwargs: url = url + "?" + urlencode(kwargs) return url def get_callback_url(self): return reverse( self.app.provider + "_callback", kwargs={"provider_id": self.app.provider_id}, ) @property def token_auth_method(self): return self.app.settings.get("token_auth_method") def get_default_scope(self): return ["openid", "profile", "email"] def extract_uid(self, data): return str(data["sub"]) def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("preferred_username"), name=data.get("name"), user_id=data.get("user_id"), picture=data.get("picture"), last_name=data.get("family_name"), first_name=data.get("given_name"), ) def extract_email_addresses(self, data): addresses = [] email = data.get("email") if email: addresses.append( EmailAddress( email=email, verified=data.get("email_verified", False), primary=True, ) ) return addresses def get_oauth2_adapter(self, request): return self.oauth2_adapter_class(request, self.app.provider_id) provider_classes = [OpenIDConnectProvider] django-allauth-65.0.2/allauth/socialaccount/providers/openid_connect/tests.py000066400000000000000000000004411467545753200275200ustar00rootroot00000000000000from allauth.socialaccount.tests import OpenIDConnectTests from allauth.tests import TestCase class MainOpenIDConnectTests(OpenIDConnectTests, TestCase): provider_id = "oidc-server" class OtherOpenIDConnectTests(OpenIDConnectTests, TestCase): provider_id = "other-oidc-server" django-allauth-65.0.2/allauth/socialaccount/providers/openid_connect/urls.py000066400000000000000000000013201467545753200273400ustar00rootroot00000000000000from django.urls import include, path, re_path from allauth.socialaccount import app_settings from . import views urlpatterns = [ re_path( r"^(?P[^/]+)/", include( [ path( "login/", views.login, name="openid_connect_login", ), path( "login/callback/", views.callback, name="openid_connect_callback", ), ] ), ) ] if app_settings.OPENID_CONNECT_URL_PREFIX: urlpatterns = [ path(f"{app_settings.OPENID_CONNECT_URL_PREFIX}/", include(urlpatterns)) ] django-allauth-65.0.2/allauth/socialaccount/providers/openid_connect/views.py000066400000000000000000000050471467545753200275220ustar00rootroot00000000000000from django.urls import reverse from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from allauth.utils import build_absolute_uri class OpenIDConnectOAuth2Adapter(OAuth2Adapter): def __init__(self, request, provider_id): self.provider_id = provider_id super().__init__(request) @property def openid_config(self): if not hasattr(self, "_openid_config"): server_url = self.get_provider().server_url resp = get_adapter().get_requests_session().get(server_url) resp.raise_for_status() self._openid_config = resp.json() return self._openid_config @property def basic_auth(self): token_auth_method = self.get_provider().app.settings.get("token_auth_method") if token_auth_method: return token_auth_method == "client_secret_basic" return "client_secret_basic" in self.openid_config.get( "token_endpoint_auth_methods_supported", [] ) @property def access_token_url(self): return self.openid_config["token_endpoint"] @property def authorize_url(self): return self.openid_config["authorization_endpoint"] @property def profile_url(self): return self.openid_config["userinfo_endpoint"] def complete_login(self, request, app, token: SocialToken, **kwargs): response = ( get_adapter() .get_requests_session() .get(self.profile_url, headers={"Authorization": "Bearer " + token.token}) ) response.raise_for_status() extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) def get_callback_url(self, request, app): callback_url = reverse( "openid_connect_callback", kwargs={"provider_id": self.provider_id} ) protocol = self.redirect_uri_protocol return build_absolute_uri(request, callback_url, protocol) @login_not_required def login(request, provider_id): view = OAuth2LoginView.adapter_view( OpenIDConnectOAuth2Adapter(request, provider_id) ) return view(request) @login_not_required def callback(request, provider_id): view = OAuth2CallbackView.adapter_view( OpenIDConnectOAuth2Adapter(request, provider_id) ) return view(request) django-allauth-65.0.2/allauth/socialaccount/providers/openstreetmap/000077500000000000000000000000001467545753200257045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openstreetmap/__init__.py000066400000000000000000000000001467545753200300030ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/openstreetmap/provider.py000066400000000000000000000017551467545753200301200ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.openstreetmap.views import ( OpenStreetMapOAuthAdapter, ) class OpenStreetMapAccount(ProviderAccount): def get_profile_url(self): return ( "https://www.openstreetmap.org/user/" + self.account.extra_data["display_name"] ) def get_avatar_url(self): return self.account.extra_data.get("avatar") def get_username(self): return self.account.extra_data["display_name"] class OpenStreetMapProvider(OAuthProvider): id = "openstreetmap" name = "OpenStreetMap" account_class = OpenStreetMapAccount oauth_adapter_class = OpenStreetMapOAuthAdapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict(username=data["display_name"]) provider_classes = [OpenStreetMapProvider] django-allauth-65.0.2/allauth/socialaccount/providers/openstreetmap/tests.py000066400000000000000000000031711467545753200274220ustar00rootroot00000000000000from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import OpenStreetMapProvider class OpenStreetMapTests(OAuthTestsMixin, TestCase): provider_id = OpenStreetMapProvider.id def get_mocked_response(self): return [ MockedResponse( 200, r""" """, ) ] # noqa def get_expected_to_str(self): return "Steve" def test_login(self): super().test_login() account = SocialAccount.objects.get(uid="1") osm_account = account.get_provider_account() self.assertEqual(osm_account.get_username(), "Steve") self.assertEqual( osm_account.get_avatar_url(), "https://secure.gravatar.com/avatar.jpg", ) self.assertEqual( osm_account.get_profile_url(), "https://www.openstreetmap.org/user/Steve", ) self.assertEqual(osm_account.to_str(), "Steve") django-allauth-65.0.2/allauth/socialaccount/providers/openstreetmap/urls.py000066400000000000000000000002631467545753200272440ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import OpenStreetMapProvider urlpatterns = default_urlpatterns(OpenStreetMapProvider) django-allauth-65.0.2/allauth/socialaccount/providers/openstreetmap/views.py000066400000000000000000000030511467545753200274120ustar00rootroot00000000000000from xml.etree import ElementTree from xml.parsers.expat import ExpatError from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class OpenStreetMapAPI(OAuth): url = "https://api.openstreetmap.org/api/0.6/user/details" def get_user_info(self): raw_xml = self.query(self.url) try: user_element = ElementTree.fromstring(raw_xml).find("user") user_info = user_element.attrib user_avatar = user_element.find("img") if user_avatar is not None: user_info.update({"avatar": user_avatar.attrib.get("href")}) return user_info except (ExpatError, KeyError, IndexError): return None class OpenStreetMapOAuthAdapter(OAuthAdapter): provider_id = "openstreetmap" request_token_url = "https://www.openstreetmap.org/oauth/request_token" access_token_url = "https://www.openstreetmap.org/oauth/access_token" authorize_url = "https://www.openstreetmap.org/oauth/authorize" def complete_login(self, request, app, token, response): client = OpenStreetMapAPI( request, app.client_id, app.secret, self.request_token_url ) extra_data = client.get_user_info() return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(OpenStreetMapOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(OpenStreetMapOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/orcid/000077500000000000000000000000001467545753200241165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/orcid/__init__.py000066400000000000000000000000001467545753200262150ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/orcid/provider.py000066400000000000000000000031261467545753200263240ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.orcid.views import OrcidOAuth2Adapter class Scope: USERINFO_PROFILE = "/authenticate" class OrcidAccount(ProviderAccount): def get_profile_url(self): return extract_from_dict(self.account.extra_data, ["orcid-identifier", "uri"]) class OrcidProvider(OAuth2Provider): id = "orcid" name = "Orcid.org" account_class = OrcidAccount oauth2_adapter_class = OrcidOAuth2Adapter def get_default_scope(self): return [Scope.USERINFO_PROFILE] def extract_uid(self, data): return extract_from_dict(data, ["orcid-identifier", "path"]) def extract_common_fields(self, data): common_fields = dict( email=extract_from_dict(data, ["person", "emails", "email", 0, "email"]), last_name=extract_from_dict( data, ["person", "name", "family-name", "value"] ), first_name=extract_from_dict( data, ["person", "name", "given-names", "value"] ), ) return dict((key, value) for (key, value) in common_fields.items() if value) provider_classes = [OrcidProvider] def extract_from_dict(data, path): """ Navigate `data`, a multidimensional array (list or dictionary), and returns the object at `path`. """ value = data try: for key in path: value = value[key] return value except (KeyError, IndexError, TypeError): return "" django-allauth-65.0.2/allauth/socialaccount/providers/orcid/tests.py000066400000000000000000000265001467545753200256350ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import OrcidProvider class OrcidTests(OAuth2TestsMixin, TestCase): provider_id = OrcidProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "orcid-identifier": { "uri": "https://sandbox.orcid.org/0000-0001-6796-198X", "path": "0000-0001-6796-198X", "host": "sandbox.orcid.org" }, "preferences": { "locale": "EN" }, "history": { "creation-method": "MEMBER_REFERRED", "completion-date": null, "submission-date": { "value": 1456951327337 }, "last-modified-date": { "value": 1519493486728 }, "claimed": true, "source": null, "deactivation-date": null, "verified-email": true, "verified-primary-email": true }, "person": { "last-modified-date": { "value": 1519493469738 }, "name": { "created-date": { "value": 1460669254582 }, "last-modified-date": { "value": 1460669254582 }, "given-names": { "value": "Patricia" }, "family-name": { "value": "Lawrence" }, "credit-name": null, "source": null, "visibility": "PUBLIC", "path": "0000-0001-6796-198X" }, "other-names": { "last-modified-date": null, "other-name": [], "path": "/0000-0001-6796-198X/other-names" }, "biography": { "created-date": { "value": 1460669254583 }, "last-modified-date": { "value": 1460669254583 }, "content": null, "visibility": "PUBLIC", "path": "/0000-0001-6796-198X/biography" }, "researcher-urls": { "last-modified-date": null, "researcher-url": [], "path": "/0000-0001-6796-198X/researcher-urls" }, "emails": { "last-modified-date": { "value": 1519493469738 }, "email": [ { "created-date": { "value": 1456951327661 }, "last-modified-date": { "value": 1519493469738 }, "source": { "source-orcid": { "uri": "https://sandbox.orcid.org/0000-0001-6796-198X", "path": "0000-0001-6796-198X", "host": "sandbox.orcid.org" }, "source-client-id": null, "source-name": { "value": "Patricia Lawrence" } }, "email": "lawrencepatricia@mailinator.com", "path": null, "visibility": "PUBLIC", "verified": true, "primary": true, "put-code": null } ], "path": "/0000-0001-6796-198X/email" }, "addresses": { "last-modified-date": null, "address": [], "path": "/0000-0001-6796-198X/address" }, "keywords": { "last-modified-date": null, "keyword": [], "path": "/0000-0001-6796-198X/keywords" }, "external-identifiers": { "last-modified-date": null, "external-identifier": [], "path": "/0000-0001-6796-198X/external-identifiers" }, "path": "/0000-0001-6796-198X/person" }, "activities-summary": { "last-modified-date": { "value": 1513777479628 }, "educations": { "last-modified-date": { "value": 1459957293365 }, "education-summary": [ { "created-date": { "value": 1459957293365 }, "last-modified-date": { "value": 1459957293365 }, "source": { "source-orcid": { "uri": "https://sandbox.orcid.org/0000-0001-6796-198X", "path": "0000-0001-6796-198X", "host": "sandbox.orcid.org" }, "source-client-id": null, "source-name": { "value": "Patricia Lawrence" } }, "department-name": null, "role-title": null, "start-date": null, "end-date": null, "organization": { "name": "Polytech'Rambouillet", "address": { "city": "Rambouillet", "region": null, "country": "FR" }, "disambiguated-organization": null }, "visibility": "PUBLIC", "put-code": 19996, "path": "/0000-0001-6796-198X/education/19996" } ], "path": "/0000-0001-6796-198X/educations" }, "employments": { "last-modified-date": { "value": 1513777479628 }, "employment-summary": [ { "created-date": { "value": 1510399314937 }, "last-modified-date": { "value": 1513777479628 }, "source": { "source-orcid": { "uri": "https://sandbox.orcid.org/0000-0001-6796-198X", "path": "0000-0001-6796-198X", "host": "sandbox.orcid.org" }, "source-client-id": null, "source-name": { "value": "Patricia Lawrence" } }, "department-name": null, "role-title": null, "start-date": { "year": { "value": "2015" }, "month": { "value": "03" }, "day": { "value": "02" } }, "end-date": null, "organization": { "name": "École nationale supérieure de céramique industrielle", "address": { "city": "Limoges", "region": null, "country": "FR" }, "disambiguated-organization": { "disambiguated-organization-identifier": "105362", "disambiguation-source": "RINGGOLD" } }, "visibility": "PUBLIC", "put-code": 29138, "path": "/0000-0001-6796-198X/employment/29138" }, { "created-date": { "value": 1502366640610 }, "last-modified-date": { "value": 1513777467282 }, "source": { "source-orcid": { "uri": "https://sandbox.orcid.org/0000-0001-6796-198X", "path": "0000-0001-6796-198X", "host": "sandbox.orcid.org" }, "source-client-id": null, "source-name": { "value": "Patricia Lawrence" } }, "department-name": null, "role-title": null, "start-date": { "year": { "value": "2002" }, "month": { "value": "02" }, "day": { "value": "16" } }, "end-date": { "year": { "value": "2015" }, "month": { "value": "08" }, "day": { "value": "12" } }, "organization": { "name": "University of Cambridge", "address": { "city": "Cambridge", "region": "Cambridgeshire", "country": "GB" }, "disambiguated-organization": { "disambiguated-organization-identifier": "2152", "disambiguation-source": "RINGGOLD" } }, "visibility": "PUBLIC", "put-code": 27562, "path": "/0000-0001-6796-198X/employment/27562" } ], "path": "/0000-0001-6796-198X/employments" }, "fundings": { "last-modified-date": null, "group": [], "path": "/0000-0001-6796-198X/fundings" }, "peer-reviews": { "last-modified-date": null, "group": [], "path": "/0000-0001-6796-198X/peer-reviews" }, "works": { "last-modified-date": { "value": 1459957753077 }, "group": [ { "last-modified-date": { "value": 1459957753077 }, "external-ids": { "external-id": [] }, "work-summary": [ { "put-code": 583440, "created-date": { "value": 1459957753047 }, "last-modified-date": { "value": 1459957753077 }, "source": { "source-orcid": { "uri": "https://sandbox.orcid.org/0000-0001-6796-198X", "path": "0000-0001-6796-198X", "host": "sandbox.orcid.org" }, "source-client-id": null, "source-name": { "value": "Patricia Lawrence" } }, "title": { "title": { "value": "Standard & Poor's fiscal methodology reviewed" }, "subtitle": null, "translated-title": null }, "external-ids": { "external-id": [] }, "type": "JOURNAL_ARTICLE", "publication-date": { "year": { "value": "2001" }, "month": { "value": "07" }, "day": { "value": "14" }, "media-type": null }, "visibility": "PUBLIC", "path": "/0000-0001-6796-198X/work/583440", "display-index": "0" } ] } ], "path": "/0000-0001-6796-198X/works" }, "path": "/0000-0001-6796-198X/activities" }, "path": "/0000-0001-6796-198X" } """, ) def get_expected_to_str(self): return "Orcid.org" def get_login_response_json(self, with_refresh_token=True): # TODO: This is not an actual response. I added this in order # to get the test suite going but did not verify to check the # exact response being returned. return """ { "access_token": "testac", "expires_in": 631138026, "token_type": "bearer", "orcid": "0000-0001-6796-198X", "scope": "/orcid-profile/read-limited", "refresh_token": "testrf" }""" django-allauth-65.0.2/allauth/socialaccount/providers/orcid/urls.py000066400000000000000000000002441467545753200254550ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import OrcidProvider urlpatterns = default_urlpatterns(OrcidProvider) django-allauth-65.0.2/allauth/socialaccount/providers/orcid/views.py000066400000000000000000000031331467545753200256250ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class OrcidOAuth2Adapter(OAuth2Adapter): provider_id = "orcid" # http://support.orcid.org/knowledgebase/articles/335483-the-public- # client-orcid-api member_api_default = False base_domain_default = "orcid.org" settings = app_settings.PROVIDERS.get(provider_id, {}) base_domain = settings.get("BASE_DOMAIN", base_domain_default) member_api = settings.get("MEMBER_API", member_api_default) api_domain = "{0}.{1}".format("api" if member_api else "pub", base_domain) authorize_url = "https://{0}/oauth/authorize".format(base_domain) access_token_url = "https://{0}/oauth/token".format(api_domain) profile_url = "https://{0}/v2.1/%s/record".format(api_domain) def complete_login(self, request, app, token, **kwargs): params = {} if self.member_api: params["access_token"] = token.token resp = ( get_adapter() .get_requests_session() .get( self.profile_url % kwargs["response"]["orcid"], params=params, headers={"accept": "application/orcid+json"}, ) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(OrcidOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(OrcidOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/patreon/000077500000000000000000000000001467545753200244665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/patreon/__init__.py000066400000000000000000000000001467545753200265650ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/patreon/constants.py000066400000000000000000000005011467545753200270500ustar00rootroot00000000000000from django.conf import settings PROVIDER_ID = "patreon" API_VERSION = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("patreon", {}) .get("VERSION", "v1") ) USE_API_V2 = True if API_VERSION == "v2" else False API_URL = "https://www.patreon.com/api/oauth2/" + (API_VERSION if USE_API_V2 else "api") django-allauth-65.0.2/allauth/socialaccount/providers/patreon/models.py000066400000000000000000000000001467545753200263110ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/patreon/provider.py000066400000000000000000000026311467545753200266740ustar00rootroot00000000000000""" Provider for Patreon """ from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.patreon.views import PatreonOAuth2Adapter from .constants import PROVIDER_ID, USE_API_V2 class PatreonAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("attributes").get("thumb_url") def to_str(self): email = self.account.extra_data.get("attributes", {}).get("email") return email or super().to_str() class PatreonProvider(OAuth2Provider): id = PROVIDER_ID name = "Patreon" account_class = PatreonAccount oauth2_adapter_class = PatreonOAuth2Adapter def get_default_scope(self): if USE_API_V2: return [ "identity", "identity[email]", "campaigns", "campaigns.members", ] return ["pledges-to-me", "users", "my-campaign"] def extract_uid(self, data): return data.get("id") def extract_common_fields(self, data): details = data["attributes"] return { "email": details.get("email"), "fullname": details.get("full_name"), "first_name": details.get("first_name"), "last_name": details.get("last_name"), } provider_classes = [PatreonProvider] django-allauth-65.0.2/allauth/socialaccount/providers/patreon/tests.py000066400000000000000000000037171467545753200262120ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import PatreonProvider class PatreonTests(OAuth2TestsMixin, TestCase): provider_id = PatreonProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "data": { "relationships": { "pledges": { "data": [{ "type": "pledge", "id": "123456" }] } }, "attributes": { "last_name": "Interwebs", "is_suspended": false, "has_password": true, "full_name": "John Interwebs", "is_nuked": false, "first_name": "John", "social_connections": { "spotify": null, "discord": null, "twitter": null, "youtube": null, "facebook": null, "deviantart": null, "twitch": null }, "twitter": null, "is_email_verified": true, "facebook_id": null, "email": "john@example.com", "facebook": null, "thumb_url": "https://c8.patreon.com/100/123456", "vanity": null, "about": null, "is_deleted": false, "created": "2017-05-05T05:16:34+00:00", "url": "https://www.patreon.com/user?u=123456", "gender": 0, "youtube": null, "discord_id": null, "image_url": "https://c8.patreon.com/400/123456", "twitch": null }, "type": "user", "id": "123456" } }""", ) # noqa def get_expected_to_str(self): return "john@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/patreon/urls.py000066400000000000000000000003111467545753200260200ustar00rootroot00000000000000"""URLs for Patreon Provider""" from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import PatreonProvider urlpatterns = default_urlpatterns(PatreonProvider) django-allauth-65.0.2/allauth/socialaccount/providers/patreon/views.py000066400000000000000000000044261467545753200262030ustar00rootroot00000000000000""" Views for PatreonProvider https://www.patreon.com/platform/documentation/oauth """ from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .constants import API_URL, PROVIDER_ID, USE_API_V2 class PatreonOAuth2Adapter(OAuth2Adapter): provider_id = PROVIDER_ID access_token_url = "https://www.patreon.com/api/oauth2/token" authorize_url = "https://www.patreon.com/oauth2/authorize" profile_url = "{0}/{1}".format( API_URL, ( "identity?include=memberships&fields%5Buser%5D=email,first_name," "full_name,image_url,last_name,social_connections," "thumb_url,url,vanity" if USE_API_V2 else "current_user" ), ) def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer " + token.token}, ) ) extra_data = resp.json().get("data") if USE_API_V2: # Extract tier/pledge level for Patreon API v2: try: member_id = extra_data["relationships"]["memberships"]["data"][0]["id"] member_url = ( "{0}/members/{1}?include=" "currently_entitled_tiers&fields%5Btier%5D=title" ).format(API_URL, member_id) resp_member = ( get_adapter() .get_requests_session() .get( member_url, headers={"Authorization": "Bearer " + token.token}, ) ) pledge_title = resp_member.json()["included"][0]["attributes"]["title"] extra_data["pledge_level"] = pledge_title except (KeyError, IndexError): extra_data["pledge_level"] = None pass return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(PatreonOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(PatreonOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/paypal/000077500000000000000000000000001467545753200243045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/paypal/__init__.py000066400000000000000000000000001467545753200264030ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/paypal/provider.py000066400000000000000000000020471467545753200265130ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.paypal.views import PaypalOAuth2Adapter class PaypalAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("picture") class PaypalProvider(OAuth2Provider): id = "paypal" name = "Paypal" account_class = PaypalAccount oauth2_adapter_class = PaypalOAuth2Adapter def get_default_scope(self): # See: https://developer.paypal.com/docs/integration/direct/identity/attributes/ # noqa return ["openid", "email"] def extract_uid(self, data): return str(data["user_id"]) def extract_common_fields(self, data): # See: https://developer.paypal.com/docs/api/#get-user-information return dict( first_name=data.get("given_name", ""), last_name=data.get("family_name", ""), email=data.get("email"), ) provider_classes = [PaypalProvider] django-allauth-65.0.2/allauth/socialaccount/providers/paypal/tests.py000066400000000000000000000012561467545753200260240ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import PaypalProvider class PaypalTests(OAuth2TestsMixin, TestCase): provider_id = PaypalProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "user_id": "https://www.paypal.com/webapps/auth/server/64ghr894040044", "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "email": "janedoe@example.com" } """, ) def get_expected_to_str(self): return "janedoe@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/paypal/urls.py000066400000000000000000000002461467545753200256450ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import PaypalProvider urlpatterns = default_urlpatterns(PaypalProvider) django-allauth-65.0.2/allauth/socialaccount/providers/paypal/views.py000066400000000000000000000030031467545753200260070ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class PaypalOAuth2Adapter(OAuth2Adapter): provider_id = "paypal" @property def authorize_url(self): path = "webapps/auth/protocol/openidconnect/v1/authorize" return "https://www.{0}/{1}".format(self._get_endpoint(), path) @property def access_token_url(self): path = "v1/identity/openidconnect/tokenservice" return "https://api.{0}/{1}".format(self._get_endpoint(), path) @property def profile_url(self): path = "v1/identity/openidconnect/userinfo" return "https://api.{0}/{1}".format(self._get_endpoint(), path) def _get_endpoint(self): settings = self.get_provider().get_settings() if settings.get("MODE") == "live": return "paypal.com" else: return "sandbox.paypal.com" def complete_login(self, request, app, token, **kwargs): response = ( get_adapter() .get_requests_session() .post( self.profile_url, params={"schema": "openid", "access_token": token.token}, ) ) extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(PaypalOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(PaypalOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/pinterest/000077500000000000000000000000001467545753200250335ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/pinterest/__init__.py000066400000000000000000000000001467545753200271320ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/pinterest/provider.py000066400000000000000000000036461467545753200272500ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.pinterest.views import ( PinterestOAuth2Adapter, ) class PinterestAccount(ProviderAccount): def get_username(self): return self.account.extra_data.get("username") def get_profile_url(self): # v5 extra_data not same as v1 username = self.get_username() if username: return "https://www.pinterest.com/{}/".format(username) return self.account.extra_data.get("url") def get_avatar_url(self): return self.account.extra_data.get("profile_image") class PinterestProvider(OAuth2Provider): id = "pinterest" name = "Pinterest" account_class = PinterestAccount oauth2_adapter_class = PinterestOAuth2Adapter @property def api_version(self): return self.get_settings().get("API_VERSION", "v1") def get_default_scope(self): # See: https://developers.pinterest.com/docs/api/overview/#scopes if self.api_version == "v5": # See: https://developers.pinterest.com/docs/getting-started/scopes/ return ["user_accounts:read"] elif self.api_version == "v3": return ["read_users"] return ["read_public"] def extract_extra_data(self, data): if self.api_version == "v5": return data return data.get("data", {}) def extract_uid(self, data): if self.api_version == "v5": return data["username"] return str(data["data"]["id"]) def extract_common_fields(self, data): if self.api_version == "v5": return dict(username=data["username"]) return dict( first_name=data.get("data", {}).get("first_name"), last_name=data.get("data", {}).get("last_name"), ) provider_classes = [PinterestProvider] django-allauth-65.0.2/allauth/socialaccount/providers/pinterest/tests.py000066400000000000000000000027601467545753200265540ustar00rootroot00000000000000from django.test.utils import override_settings from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import PinterestProvider class PinterestTests(OAuth2TestsMixin, TestCase): provider_id = PinterestProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "data": { "url": "https://www.pinterest.com/muravskiyyarosl/", "first_name": "Jane", "last_name": "Doe", "id": "351247977031674143" } } """, ) def get_expected_to_str(self): return "Jane Doe" @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=False, SOCIALACCOUNT_PROVIDERS={ "pinterest": { "API_VERSION": "v5", } }, ) def test_login_v5(self): self.provider_id = PinterestProvider.id resp = self.login( MockedResponse( 200, """ { "account_type": "BUSINESS", "profile_image": "https://i.pinimg.com/280x280_RS/5c/88/2f/5c882f4b02468fcd6cda2ce569c2c166.jpg", "website_url": "https://sns-sdks.github.io/", "username": "enjoylifebot" } """, ), ) assert resp.status_code == 302 django-allauth-65.0.2/allauth/socialaccount/providers/pinterest/urls.py000066400000000000000000000002541467545753200263730ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import PinterestProvider urlpatterns = default_urlpatterns(PinterestProvider) django-allauth-65.0.2/allauth/socialaccount/providers/pinterest/views.py000066400000000000000000000034421467545753200265450ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class PinterestOAuth2Adapter(OAuth2Adapter): provider_id = "pinterest" provider_default_url = "api.pinterest.com" provider_default_api_version = "v1" settings = app_settings.PROVIDERS.get(provider_id, {}) provider_base_url = settings.get("PINTEREST_URL", provider_default_url) provider_api_version = settings.get("API_VERSION", provider_default_api_version) authorize_url = "https://www.pinterest.com/oauth/" access_token_url = "https://{0}/{1}/oauth/token".format( provider_base_url, provider_api_version ) basic_auth = True if provider_api_version == "v5": profile_url = "https://{0}/{1}/user_account".format( provider_base_url, provider_api_version ) elif provider_api_version == "v3": profile_url = "https://{0}/{1}/users/me".format( provider_base_url, provider_api_version ) else: profile_url = "https://{0}/{1}/me".format( provider_base_url, provider_api_version ) if provider_api_version == "v3": access_token_method = "PUT" def complete_login(self, request, app, token, **kwargs): response = ( get_adapter() .get_requests_session() .get(self.profile_url, headers={"Authorization": "Bearer " + token.token}) ) extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(PinterestOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(PinterestOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/pocket/000077500000000000000000000000001467545753200243035ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/pocket/__init__.py000066400000000000000000000000001467545753200264020ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/pocket/client.py000066400000000000000000000066731467545753200261470ustar00rootroot00000000000000from urllib.parse import urlencode from django.http import HttpResponseRedirect from django.utils.translation import gettext as _ from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth.client import ( OAuthClient, OAuthError, get_token_prefix, ) from allauth.utils import build_absolute_uri class PocketOAuthClient(OAuthClient): def _get_request_token(self): """ Obtain a temporary request token to authorize an access token and to sign the request to obtain the access token """ if self.request_token is None: redirect_url = build_absolute_uri(self.request, self.callback_url) headers = { "X-Accept": "application/json", } data = { "consumer_key": self.consumer_key, "redirect_uri": redirect_url, } response = ( get_adapter() .get_requests_session() .post( url=self.request_token_url, json=data, headers=headers, ) ) if response.status_code != 200: raise OAuthError( _("Invalid response while obtaining request token" ' from "%s".') % get_token_prefix(self.request_token_url) ) self.request_token = response.json()["code"] self.request.session[ "oauth_%s_request_token" % get_token_prefix(self.request_token_url) ] = self.request_token return self.request_token def get_redirect(self, authorization_url, extra_params): """ Returns a ``HttpResponseRedirect`` object to redirect the user to the Pocket authorization URL. """ request_token = self._get_request_token() params = { "request_token": request_token, "redirect_uri": self.request.build_absolute_uri(self.callback_url), } params.update(extra_params) url = authorization_url + "?" + urlencode(params) return HttpResponseRedirect(url) def get_access_token(self): """ Obtain the access token to access private resources at the API endpoint. """ if self.access_token is None: request_token = self._get_rt_from_session() url = self.access_token_url headers = { "X-Accept": "application/json", } data = { "consumer_key": self.consumer_key, "code": request_token, } response = ( get_adapter() .get_requests_session() .post(url=url, headers=headers, json=data) ) if response.status_code != 200: raise OAuthError( _("Invalid response while obtaining access token" ' from "%s".') % get_token_prefix(self.request_token_url) ) r = response.json() self.access_token = { "oauth_token": request_token, "oauth_token_secret": r["access_token"], "username": r["username"], } self.request.session[ "oauth_%s_access_token" % get_token_prefix(self.request_token_url) ] = self.access_token return self.access_token django-allauth-65.0.2/allauth/socialaccount/providers/pocket/models.py000066400000000000000000000000001467545753200261260ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/pocket/provider.py000066400000000000000000000016001467545753200265040ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.pocket.views import PocketOAuthAdapter class PocketAccount(ProviderAccount): pass class PocketProvider(OAuthProvider): id = "pocket" name = "Pocket" account_class = PocketAccount oauth_adapter_class = PocketOAuthAdapter def extract_uid(self, data): return data["username"] def extract_common_fields(self, data): return dict( email=data["username"], ) def extract_email_addresses(self, data): return [ EmailAddress( email=data["username"], verified=True, primary=True, ) ] provider_classes = [PocketProvider] django-allauth-65.0.2/allauth/socialaccount/providers/pocket/tests.py000066400000000000000000000027651467545753200260310ustar00rootroot00000000000000from urllib.parse import parse_qs, urlencode, urlparse from django.urls import reverse from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .provider import PocketProvider class PocketOAuthTests(OAuthTestsMixin, TestCase): provider_id = PocketProvider.id def get_mocked_response(self): return [] def get_expected_to_str(self): return "name@example.com" def get_access_token_response(self): return MockedResponse( 200, """ {"access_token":"5678defg-5678-defg-5678-defg56", "username":"name@example.com"} """, ) def login(self, resp_mocks, process="login"): with mocked_response( MockedResponse( 200, """ {"code": "dcba4321-dcba-4321-dcba-4321dc"} """, {"content-type": "application/json"}, ) ): resp = self.client.post( reverse(self.provider.id + "_login") + "?" + urlencode(dict(process=process)) ) p = urlparse(resp["location"]) q = parse_qs(p.query) complete_url = reverse(self.provider.id + "_callback") self.assertGreater(q["redirect_uri"][0].find(complete_url), 0) with mocked_response(self.get_access_token_response(), *resp_mocks): resp = self.client.get(complete_url) return resp django-allauth-65.0.2/allauth/socialaccount/providers/pocket/urls.py000066400000000000000000000002451467545753200256430ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import PocketProvider urlpatterns = default_urlpatterns(PocketProvider) django-allauth-65.0.2/allauth/socialaccount/providers/pocket/views.py000066400000000000000000000012521467545753200260120ustar00rootroot00000000000000from ..oauth.views import OAuthAdapter, OAuthCallbackView, OAuthLoginView from .client import PocketOAuthClient class PocketOAuthAdapter(OAuthAdapter): provider_id = "pocket" request_token_url = "https://getpocket.com/v3/oauth/request" access_token_url = "https://getpocket.com/v3/oauth/authorize" authorize_url = "https://getpocket.com/auth/authorize" client_class = PocketOAuthClient def complete_login(self, request, app, token, response): return self.get_provider().sociallogin_from_response(request, response) oauth_login = OAuthLoginView.adapter_view(PocketOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(PocketOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/questrade/000077500000000000000000000000001467545753200250135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/questrade/__init__.py000066400000000000000000000000001467545753200271120ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/questrade/provider.py000066400000000000000000000010701467545753200272150ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.questrade.views import ( QuestradeOAuth2Adapter, ) class QuestradeAccount(ProviderAccount): pass class QuestradeProvider(OAuth2Provider): id = "questrade" name = "Questrade" account_class = QuestradeAccount oauth2_adapter_class = QuestradeOAuth2Adapter def extract_uid(self, data): return str(data["userId"]) provider_classes = [QuestradeProvider] django-allauth-65.0.2/allauth/socialaccount/providers/questrade/tests.py000066400000000000000000000006751467545753200265370ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import QuestradeProvider class QuestradeTests(OAuth2TestsMixin, TestCase): provider_id = QuestradeProvider.id def get_mocked_response(self): return MockedResponse( 200, """{"userId":400,"accounts":[]}""", ) def get_expected_to_str(self): return "Questrade" django-allauth-65.0.2/allauth/socialaccount/providers/questrade/urls.py000066400000000000000000000002541467545753200263530ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import QuestradeProvider urlpatterns = default_urlpatterns(QuestradeProvider) django-allauth-65.0.2/allauth/socialaccount/providers/questrade/views.py000066400000000000000000000022051467545753200265210ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class QuestradeOAuth2Adapter(OAuth2Adapter): provider_id = "questrade" access_token_url = "https://login.questrade.com/oauth2/token" authorize_url = "https://login.questrade.com/oauth2/authorize" supports_state = False def complete_login(self, request, app, token, **kwargs): api_server = kwargs.get("response", {}).get( "api_server", "https://api01.iq.questrade.com/" ) resp = ( get_adapter() .get_requests_session() .get( "{}v1/accounts".format(api_server), headers={"Authorization": "Bearer {}".format(token.token)}, ) ) resp.raise_for_status() data = resp.json() data.update(kwargs) return self.get_provider().sociallogin_from_response(request, data) oauth2_login = OAuth2LoginView.adapter_view(QuestradeOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(QuestradeOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/000077500000000000000000000000001467545753200251705ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/__init__.py000066400000000000000000000000001467545753200272670ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/models.py000066400000000000000000000000001467545753200270130ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/provider.py000066400000000000000000000034161467545753200274000ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ( ProviderAccount, ProviderException, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.quickbooks.views import ( QuickBooksOAuth2Adapter, ) class QuickBooksAccount(ProviderAccount): pass class QuickBooksOAuth2Provider(OAuth2Provider): id = "quickbooks" # Name is displayed to ordinary users -- don't include protocol name = "QuickBooks" account_class = QuickBooksAccount oauth2_adapter_class = QuickBooksOAuth2Adapter def extract_uid(self, data): if "sub" not in data: raise ProviderException("QBO error", data) return str(data["sub"]) def get_profile_fields(self): default_fields = [ "address", "sub", "phoneNumber", "givenName", "familyName", "email", "emailVerified", ] fields = self.get_settings().get("PROFILE_FIELDS", default_fields) return fields def get_default_scope(self): scope = [ "openid", "com.intuit.quickbooks.accounting", "profile", "phone", ] if app_settings.QUERY_EMAIL: scope.append("email") return scope def extract_common_fields(self, data): return dict( email=data.get("email"), address=data.get("address"), sub=data.get("sub"), givenName=data.get("givenName"), familynName=data.get("familyName"), emailVerified=data.get("emailVerified"), phoneNumber=data.get("phoneNumber"), ) provider_classes = [QuickBooksOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/tests.py000066400000000000000000000013171467545753200267060ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import QuickBooksOAuth2Provider class QuickBooksOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = QuickBooksOAuth2Provider.id def get_mocked_response(self): return MockedResponse( 200, """ { "sub": "d8752092-0f2b-4b6e-86ef-6b72f2457a00", "emailVerified": true, "familyName": "Mckeeman", "phoneNumber": "+1 4156694355", "givenName": "Darren", "phoneNumberVerified": true, "email": "darren@blocklight.io"} """, ) def get_expected_to_str(self): return "darren@blocklight.io" django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/urls.py000066400000000000000000000002721467545753200265300ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import QuickBooksOAuth2Provider urlpatterns = default_urlpatterns(QuickBooksOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/quickbooks/views.py000066400000000000000000000031331467545753200266770ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class QuickBooksOAuth2Adapter(OAuth2Adapter): provider_id = "quickbooks" access_token_url = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" authorize_url = "https://appcenter.intuit.com/connect/oauth2" profile_test = "https://sandbox-accounts.platform.intuit.com/v1/openid_connect/userinfo" # NOQA profile_url = "https://accounts.platform.intuit.com/v1/openid_connect/userinfo" profile_url_method = "GET" access_token_method = "POST" def complete_login(self, request, app, token, **kwargs): realm_id = request.GET.get("realmId") extra_data = self.get_user_info(token) if realm_id: extra_data["realmId"] = realm_id return self.get_provider().sociallogin_from_response(request, extra_data) def get_user_info(self, token): auth_header = "Bearer " + token.token headers = { "Accept": "application/json", "Authorization": auth_header, "accept": "application/json", } is_sandbox = self.get_provider().get_settings().get("SANDBOX", False) url = self.profile_test if is_sandbox else self.profile_url resp = get_adapter().get_requests_session().get(url, headers=headers) resp.raise_for_status() return resp.json() oauth2_login = OAuth2LoginView.adapter_view(QuickBooksOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(QuickBooksOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/reddit/000077500000000000000000000000001467545753200242715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/reddit/__init__.py000066400000000000000000000000001467545753200263700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/reddit/provider.py000077500000000000000000000012601467545753200264770ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.reddit.views import RedditAdapter class RedditAccount(ProviderAccount): pass class RedditProvider(OAuth2Provider): id = "reddit" name = "Reddit" account_class = RedditAccount oauth2_adapter_class = RedditAdapter def extract_uid(self, data): return data["name"] def extract_common_fields(self, data): return dict(username=data.get("name")) def get_default_scope(self): scope = ["identity"] return scope provider_classes = [RedditProvider] django-allauth-65.0.2/allauth/socialaccount/providers/reddit/tests.py000077500000000000000000000007341467545753200260140ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import RedditProvider class RedditTests(OAuth2TestsMixin, TestCase): provider_id = RedditProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """{ "name": "wayward710"}""", ) ] def get_expected_to_str(self): return "wayward710" django-allauth-65.0.2/allauth/socialaccount/providers/reddit/urls.py000077500000000000000000000002461467545753200256350ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import RedditProvider urlpatterns = default_urlpatterns(RedditProvider) django-allauth-65.0.2/allauth/socialaccount/providers/reddit/views.py000077500000000000000000000025101467545753200260010ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class RedditAdapter(OAuth2Adapter): provider_id = "reddit" access_token_url = "https://www.reddit.com/api/v1/access_token" authorize_url = "https://www.reddit.com/api/v1/authorize" profile_url = "https://oauth.reddit.com/api/v1/me" basic_auth = True settings = app_settings.PROVIDERS.get(provider_id, {}) # Allow custom User Agent to comply with reddit API limits headers = {"User-Agent": settings.get("USER_AGENT", "django-allauth-header")} def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "bearer " + token.token} headers.update(self.headers) extra_data = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) # This only here because of weird response from the test suite if isinstance(extra_data, list): extra_data = extra_data[0] return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth2_login = OAuth2LoginView.adapter_view(RedditAdapter) oauth2_callback = OAuth2CallbackView.adapter_view(RedditAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/robinhood/000077500000000000000000000000001467545753200250015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/robinhood/__init__.py000066400000000000000000000000001467545753200271000ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/robinhood/provider.py000066400000000000000000000013611467545753200272060ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.robinhood.views import ( RobinhoodOAuth2Adapter, ) class RobinhoodAccount(ProviderAccount): def get_avatar_url(self): return None class RobinhoodProvider(OAuth2Provider): id = "robinhood" name = "Robinhood" account_class = RobinhoodAccount oauth2_adapter_class = RobinhoodOAuth2Adapter def get_default_scope(self): return ["read"] def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict(username=data.get("username")) provider_classes = [RobinhoodProvider] django-allauth-65.0.2/allauth/socialaccount/providers/robinhood/tests.py000066400000000000000000000007511467545753200265200ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import RobinhoodProvider class RobinhoodTests(OAuth2TestsMixin, TestCase): provider_id = RobinhoodProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "username": "test_username", "id": "1234-5678-910" } """, ) def get_expected_to_str(self): return "test_username" django-allauth-65.0.2/allauth/socialaccount/providers/robinhood/urls.py000066400000000000000000000002541467545753200263410ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import RobinhoodProvider urlpatterns = default_urlpatterns(RobinhoodProvider) django-allauth-65.0.2/allauth/socialaccount/providers/robinhood/views.py000066400000000000000000000021311467545753200265050ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class RobinhoodOAuth2Adapter(OAuth2Adapter): provider_id = "robinhood" @property def authorize_url(self): return "https://www.robinhood.com/oauth2/authorize/" @property def access_token_url(self): return "https://api.robinhood.com/oauth2/token/" @property def profile_url(self): return "https://api.robinhood.com/user/id/" def complete_login(self, request, app, token, **kwargs): response = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer %s" % token.token}, ) ) extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(RobinhoodOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(RobinhoodOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/salesforce/000077500000000000000000000000001467545753200251445ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/salesforce/__init__.py000066400000000000000000000000001467545753200272430ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/salesforce/provider.py000066400000000000000000000033541467545753200273550ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount import providers from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.salesforce.views import ( SalesforceOAuth2Adapter, ) class SalesforceAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("link") def get_avatar_url(self): return self.account.extra_data.get("picture") class SalesforceProvider(OAuth2Provider): id = "salesforce" name = "Salesforce" package = "allauth.socialaccount.providers.salesforce" account_class = SalesforceAccount oauth2_adapter_class = SalesforceOAuth2Adapter def get_default_scope(self): return ["id", "openid"] def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["approval_prompt"] = "force" return ret def extract_uid(self, data): return str(data["user_id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), last_name=data.get("family_name"), first_name=data.get("given_name"), username=data.get("preferred_username"), ) def extract_email_addresses(self, data): # a salesforce user must have an email, but it might not be verified email = EmailAddress( email=data.get("email"), primary=True, verified=data.get("email_verified"), ) return [email] providers.registry.register(SalesforceProvider) django-allauth-65.0.2/allauth/socialaccount/providers/salesforce/tests.py000066400000000000000000000041351467545753200266630ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import SalesforceProvider class SalesforceTests(OAuth2TestsMixin, TestCase): provider_id = SalesforceProvider.id def get_mocked_response( self, last_name="Penners", first_name="Raymond", name="Raymond Penners", email="raymond.penners@gmail.com", verified_email=True, ): userinfo = USERINFO_RESPONSE.format( org_id="00Dxx00000000000A0", user_id="005xx000000aWwRQAU", vip="https://test.salesforce.com", nickname="test-ooi2xhmjteep", first_name=first_name, last_name=last_name, my_domain="https://fun.cs46.my.salesforce.com", content_domain="https://fun--c.cs46.content.force.com", verified_email=repr(verified_email).lower(), email=email, active="true", is_app_installed="true", ) return MockedResponse(200, userinfo) def get_expected_to_str(self): return "raymond.penners@gmail.com" USERINFO_RESPONSE = """ {{ "sub": "{vip}/id/{org_id}/{user_id}", "user_id": "{user_id}", "organization_id": "{org_id}", "preferred_username": "{nickname}@sample_-_dev_workspace.net", "nickname": "{nickname}", "name": "{first_name} {last_name}", "email": "{email}", "email_verified": {verified_email}, "given_name": "{first_name}", "family_name": "{last_name}", "zoneinfo": "America/Los_Angeles", "photos": {{ "picture": "{content_domain}/profilephoto/005/F", "thumbnail": "{content_domain}/profilephoto/005/T" }}, "profile": "{my_domain}/{user_id}", "picture": "{content_domain}/profilephoto/005/F", "address": {{"country": "US"}}, "urls": {{"custom_domain": "{my_domain}"}}, "active": {active}, "user_type": "STANDARD", "language": "en_US", "locale": "en_US", "utcOffset": -28800000, "updated_at": "2017-10-05T20:39:02.000+0000", "is_app_installed": {is_app_installed} }} """ django-allauth-65.0.2/allauth/socialaccount/providers/salesforce/urls.py000066400000000000000000000002561467545753200265060ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import SalesforceProvider urlpatterns = default_urlpatterns(SalesforceProvider) django-allauth-65.0.2/allauth/socialaccount/providers/salesforce/views.py000066400000000000000000000022461467545753200266570ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class SalesforceOAuth2Adapter(OAuth2Adapter): provider_id = "salesforce" @property def base_url(self): return self.get_provider().app.key @property def authorize_url(self): return "{}/services/oauth2/authorize".format(self.base_url) @property def access_token_url(self): return "{}/services/oauth2/token".format(self.base_url) @property def userinfo_url(self): return "{}/services/oauth2/userinfo".format(self.base_url) def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.userinfo_url, params={"oauth_token": token.token}) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(SalesforceOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(SalesforceOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/saml/000077500000000000000000000000001467545753200237525ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/saml/__init__.py000066400000000000000000000000001467545753200260510ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/saml/conftest.py000066400000000000000000000221751467545753200261600ustar00rootroot00000000000000import base64 from unittest.mock import patch from django.test.client import Client import pytest @pytest.fixture def client(): client = Client(HTTP_HOST="example.com") return client @pytest.fixture def saml_settings(settings): settings.SOCIALACCOUNT_PROVIDERS = { "saml": { "APPS": [ { "client_id": "org", "provider_id": "urn:dev-123.us.auth0.com", "settings": { "attribute_mapping": { "uid": "http://schemas.auth0.com/clientID", "email_verified": "http://schemas.auth0.com/email_verified", "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", }, "idp": { "name": "Test IdP", "entity_id": "urn:dev-123.us.auth0.com", "sso_url": "https://dev-123.us.auth0.com/samlp/456", "slo_url": "https://dev-123.us.auth0.com/samlp/456", "x509cert": "", }, "advanced": { "strict": False, }, }, } ] } } @pytest.fixture def acs_saml_response_factory(): def factory(in_response_to=None): xml = f""" urn:dev-123.us.auth0.com urn:dev-123.us.auth0.com 123 If7dFg... MIIDHTCC... google-oauth2|108204123456789 https://allauth.org/accounts/org/metadata/ urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified google-oauth2|108204123456789 john.doe@email.org John John john.doe@email.org google-oauth2 google-oauth2 true dummysamluid Wed Jun 28 2023 17:53:49 GMT+0000 (Coordinated Universal Time) true en john.doe https://lh3.googleusercontent.com/a/AAcHTtfZ0fEyL3BKP1Hk2v1bNwpJd6ckIeo6jSExlkVjMXaIpsY=s96-c Sat Jul 08 2023 06:13:07 GMT+0000 (Coordinated Universal Time) view-profile manage-account-links """ return base64.b64encode(xml.encode("utf8")).decode("utf8") return factory @pytest.fixture def sls_saml_request(): xml = "" return base64.b64encode(xml.encode("utf8")).decode("utf8") @pytest.fixture def mocked_signature_validation(): with patch("onelogin.saml2.utils.OneLogin_Saml2_Utils.validate_sign") as mock: mock.return_value = True yield django-allauth-65.0.2/allauth/socialaccount/providers/saml/provider.py000066400000000000000000000117401467545753200261610ustar00rootroot00000000000000from django.http import HttpResponseRedirect from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.providers.base import Provider, ProviderAccount class SAMLAccount(ProviderAccount): pass class SAMLProvider(Provider): id = "saml" name = "SAML" supports_redirect = True account_class = SAMLAccount default_attribute_mapping = { "uid": [ "urn:oasis:names:tc:SAML:attribute:subject-id", ], "email": [ "urn:oid:0.9.2342.19200300.100.1.3", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", ], "email_verified": [ "http://schemas.auth0.com/email_verified", ], "first_name": [ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", "urn:oid:2.5.4.42", ], "last_name": [ "urn:oid:2.5.4.4", ], "username": [ "http://schemas.auth0.com/nickname", ], } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.name = self.app.name or self.app.client_id or self.name def get_login_url(self, request, **kwargs): url = reverse("saml_login", kwargs={"organization_slug": self.app.client_id}) if kwargs: url = url + "?" + urlencode(kwargs) return url def extract_extra_data(self, data): return data.get_attributes() def extract_uid(self, data): """http://docs.oasis-open.org/security/saml-subject-id-attr/v1.0/csprd01/saml-subject-id-attr-v1.0-csprd01.html Quotes: "While the Attributes defined in this profile have as a goal the explicit replacement of the element as a means of subject identification, it is certainly possible to compose them with existing NameID usage provided the same subject is being identified. This can also serve as a migration strategy for existing applications." "SAML does not define an identifier that meets all of these requirements well. It does standardize a kind of NameID termed “persistent” that meets some of them in the particular case of so-called “pairwise” identification, where an identifier varies by relying party. It has seen minimal adoption outside of a few contexts, and fails at the “compact” and “simple to handle” criteria above, on top of the disadvantages inherent with all NameID usage." Overall, our strategy is to prefer a uid resulting from explicit attribute mappings, and only if there is no such uid fallback to the NameID. """ uid = self._extract(data).get("uid") if uid is None: uid = data.get_nameid() return uid def extract_common_fields(self, data): ret = self._extract(data) ret.pop("uid", None) return ret def _extract(self, data): provider_config = self.app.settings raw_attributes = data.get_attributes() attributes = {} attribute_mapping = provider_config.get( "attribute_mapping", self.default_attribute_mapping ) # map configured provider attributes for key, provider_keys in attribute_mapping.items(): if isinstance(provider_keys, str): provider_keys = [provider_keys] for provider_key in provider_keys: attribute_list = raw_attributes.get(provider_key, None) if attribute_list is not None and len(attribute_list) > 0: attributes[key] = attribute_list[0] break email_verified = attributes.get("email_verified") if email_verified: email_verified = email_verified.lower() in ["true", "1", "t", "y", "yes"] attributes["email_verified"] = email_verified # If we did not find an email, check if the NameID contains the email. if not attributes.get("email") and ( data.get_nameid_format() == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" # Alternatively, if `use_id_for_email` is true, then we always interpret the nameID as email or provider_config.get("use_nameid_for_email", False) ): attributes["email"] = data.get_nameid() return attributes def redirect(self, request, process, next_url=None, data=None, **kwargs): from allauth.socialaccount.providers.saml.utils import build_auth auth = build_auth(request, self) # If we pass `return_to=None` `auth.login` will use the URL of the # current view. redirect = auth.login(return_to="") self.stash_redirect_state( request, process, next_url, data, state_id=auth.get_last_request_id(), **kwargs ) return HttpResponseRedirect(redirect) provider_classes = [SAMLProvider] django-allauth-65.0.2/allauth/socialaccount/providers/saml/tests.py000066400000000000000000000225521467545753200254740ustar00rootroot00000000000000from unittest.mock import Mock, patch from urllib.parse import parse_qs, urlparse from django.conf import settings from django.urls import reverse, reverse_lazy from django.utils.http import urlencode import pytest from pytest_django.asserts import assertTemplateUsed from allauth.account.models import EmailAddress from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.internal import statekit from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.base.constants import AuthProcess from allauth.socialaccount.providers.saml.utils import build_saml_config @pytest.mark.parametrize( "idp_initiated,adv_settings,state_kwargs,relay_state, expected_url", [ (False, {}, {}, "/not/here", settings.LOGIN_REDIRECT_URL), (False, {}, {"next": "/here"}, "/not/here", "/here"), ( False, {}, {"process": "connect"}, "/not/here", reverse_lazy("socialaccount_connections"), ), (False, {}, {"process": "connect", "next": "/here"}, "/not/here", "/here"), (True, {"reject_idp_initiated_sso": False}, {}, "/set-by-idp", "/set-by-idp"), ( True, {"reject_idp_initiated_sso": False}, {}, "not-a-url", settings.LOGIN_REDIRECT_URL, ), (True, {}, {}, "/set-by-idp", "/set-by-idp"), ], ) def test_acs( request, idp_initiated, db, saml_settings, acs_saml_response_factory, mocked_signature_validation, expected_url, relay_state, state_kwargs, sociallogin_setup_state, adv_settings, settings, ): provider_settings = settings.SOCIALACCOUNT_PROVIDERS["saml"]["APPS"][0]["settings"] advanced = dict(provider_settings["advanced"]) advanced.update(adv_settings) provider_settings["advanced"] = advanced process = state_kwargs.setdefault("process", AuthProcess.LOGIN) is_connect = process == AuthProcess.CONNECT if is_connect: client = request.getfixturevalue("auth_client") user = request.getfixturevalue("user") else: client = request.getfixturevalue("client") user = None state_id = None if not idp_initiated: state_id = sociallogin_setup_state(client, **state_kwargs) data = {"SAMLResponse": acs_saml_response_factory(in_response_to=state_id)} if relay_state is not None: data["RelayState"] = relay_state resp = client.post( reverse("saml_acs", kwargs={"organization_slug": "org"}), data=data ) finish_url = reverse("saml_finish_acs", kwargs={"organization_slug": "org"}) assert resp.status_code == 302 assert resp["location"] == finish_url resp = client.get(finish_url) if idp_initiated and advanced.get("reject_idp_initiated_sso", True): assert "socialaccount/authentication_error.html" in ( t.name for t in resp.templates ) else: assert resp["location"] == expected_url account = SocialAccount.objects.get( provider="urn:dev-123.us.auth0.com", uid="dummysamluid" ) assert account.extra_data["Role"] == ["view-profile", "manage-account-links"] email = EmailAddress.objects.get(user=account.user) assert email.email == (user.email if is_connect else "john.doe@email.org") def test_acs_error(client, db, saml_settings): data = {"SAMLResponse": "bad-response"} resp = client.post( reverse("saml_acs", kwargs={"organization_slug": "org"}), data=data ) assert resp.status_code == 302 resp = client.get(resp["location"]) assert "socialaccount/authentication_error.html" in (t.name for t in resp.templates) def test_acs_get(client, db, saml_settings): """WHile ACS expects POST, it always redirects and handles the request in the FinishACSView. """ resp = client.get(reverse("saml_acs", kwargs={"organization_slug": "org"})) assert resp.status_code == 302 resp = client.get(resp["location"]) assert "socialaccount/authentication_error.html" in (t.name for t in resp.templates) def test_sls_get(client, db, saml_settings): """SLS expects POST""" resp = client.get(reverse("saml_sls", kwargs={"organization_slug": "org"})) assert resp.status_code == 400 def test_login_on_get(client, db, saml_settings): resp = client.get(reverse("saml_login", kwargs={"organization_slug": "org"})) assert resp.status_code == 200 assertTemplateUsed(resp, "socialaccount/login.html") def test_login(client, db, saml_settings): resp = client.post( reverse("saml_login", kwargs={"organization_slug": "org"}) + "?process=connect&next=/foo" ) assert resp.status_code == 302 location = resp["location"] assert location.startswith("https://dev-123.us.auth0.com/samlp/456?SAMLRequest=") resp_query = parse_qs(urlparse(location).query) # We're not using RelayState assert resp_query.get("RelayState") is None # We're using the request ID / InResponseTo for tracking state. state_id = list(client.session[statekit.STATES_SESSION_KEY].keys())[0] assert state_id.startswith("ONELOGIN_") state = client.session[statekit.STATES_SESSION_KEY][state_id][0] assert state == {"process": "connect", "data": None, "next": "/foo"} def test_metadata( client, db, saml_settings, ): resp = client.get(reverse("saml_metadata", kwargs={"organization_slug": "org"})) assert resp.status_code == 200 assert resp.content.startswith( b'\n[^/]+)/", include( [ path( "acs/", views.acs, name="saml_acs", ), path( "acs/finish/", views.finish_acs, name="saml_finish_acs", ), path( "sls/", views.sls, name="saml_sls", ), path( "metadata/", views.metadata, name="saml_metadata", ), path( "login/", views.login, name="saml_login", ), ] ), ) ] django-allauth-65.0.2/allauth/socialaccount/providers/saml/utils.py000066400000000000000000000146341467545753200254740ustar00rootroot00000000000000from urllib.parse import urlparse from django.core.cache import cache from django.core.exceptions import ImproperlyConfigured from django.http import Http404 from django.urls import reverse from django.utils.http import urlencode from onelogin.saml2.auth import OneLogin_Saml2_Auth from onelogin.saml2.constants import OneLogin_Saml2_Constants from onelogin.saml2.idp_metadata_parser import OneLogin_Saml2_IdPMetadataParser from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialApp from allauth.socialaccount.providers.saml.provider import SAMLProvider def get_app_or_404(request, organization_slug): adapter = get_adapter() try: return adapter.get_app( request, provider=SAMLProvider.id, client_id=organization_slug ) except SocialApp.DoesNotExist: raise Http404(f"no SocialApp found with client_id={organization_slug}") def prepare_django_request(request): result = { "https": "on" if request.is_secure() else "off", "http_host": request.META["HTTP_HOST"], "script_name": request.META["PATH_INFO"], "get_data": request.GET.copy(), # 'lowercase_urlencoding': True, "post_data": request.POST.copy(), } return result def build_sp_config(request, provider_config, org): acs_url = request.build_absolute_uri(reverse("saml_acs", args=[org])) sls_url = request.build_absolute_uri(reverse("saml_sls", args=[org])) metadata_url = request.build_absolute_uri(reverse("saml_metadata", args=[org])) # SP entity ID generated with the following precedence: # 1. Explicitly configured SP via the SocialApp.settings # 2. Fallback to the SAML metadata urlpattern _sp_config = provider_config.get("sp", {}) sp_entity_id = _sp_config.get("entity_id") sp_config = { "entityId": sp_entity_id or metadata_url, "assertionConsumerService": { "url": acs_url, "binding": OneLogin_Saml2_Constants.BINDING_HTTP_POST, }, "singleLogoutService": { "url": sls_url, "binding": OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT, }, } avd = provider_config.get("advanced", {}) if avd.get("x509cert") is not None: sp_config["x509cert"] = avd["x509cert"] if avd.get("x509cert_new"): sp_config["x509certNew"] = avd["x509cert_new"] if avd.get("private_key") is not None: sp_config["privateKey"] = avd["private_key"] if avd.get("name_id_format") is not None: sp_config["NameIDFormat"] = avd["name_id_format"] return sp_config def fetch_metadata_url_config(idp_config): metadata_url = idp_config["metadata_url"] entity_id = idp_config["entity_id"] cache_key = f"saml.metadata.{metadata_url}.{entity_id}" saml_config = cache.get(cache_key) if saml_config is None: saml_config = OneLogin_Saml2_IdPMetadataParser.parse_remote( metadata_url, entity_id=entity_id, timeout=idp_config.get("metadata_request_timeout", 10), ) cache.set( cache_key, saml_config, idp_config.get("metadata_cache_timeout", 60 * 60 * 4), ) return saml_config def build_saml_config(request, provider_config, org): avd = provider_config.get("advanced", {}) security_config = { "authnRequestsSigned": avd.get("authn_request_signed", False), "digestAlgorithm": avd.get("digest_algorithm", OneLogin_Saml2_Constants.SHA256), "logoutRequestSigned": avd.get("logout_request_signed", False), "logoutResponseSigned": avd.get("logout_response_signed", False), "requestedAuthnContext": False, "signatureAlgorithm": avd.get( "signature_algorithm", OneLogin_Saml2_Constants.RSA_SHA256 ), "signMetadata": avd.get("metadata_signed", False), "wantAssertionsEncrypted": avd.get("want_assertion_encrypted", False), "wantAssertionsSigned": avd.get("want_assertion_signed", False), "wantMessagesSigned": avd.get("want_message_signed", False), "nameIdEncrypted": avd.get("name_id_encrypted", False), "wantNameIdEncrypted": avd.get("want_name_id_encrypted", False), "allowSingleLabelDomains": avd.get("allow_single_label_domains", False), "rejectDeprecatedAlgorithm": avd.get("reject_deprecated_algorithm", True), "wantNameId": avd.get("want_name_id", False), "wantAttributeStatement": avd.get("want_attribute_statement", True), "allowRepeatAttributeName": avd.get("allow_repeat_attribute_name", True), } saml_config = { "strict": avd.get("strict", True), "security": security_config, } contact_person = provider_config.get("contact_person") if contact_person: saml_config["contactPerson"] = contact_person organization = provider_config.get("organization") if organization: saml_config["organization"] = organization idp = provider_config.get("idp") if idp is None: raise ImproperlyConfigured("`idp` missing") metadata_url = idp.get("metadata_url") if metadata_url: meta_config = fetch_metadata_url_config(idp) saml_config["idp"] = meta_config["idp"] else: saml_config["idp"] = { "entityId": idp["entity_id"], "x509cert": idp["x509cert"], "singleSignOnService": {"url": idp["sso_url"]}, } slo_url = idp.get("slo_url") if slo_url: saml_config["idp"]["singleLogoutService"] = {"url": slo_url} saml_config["sp"] = build_sp_config(request, provider_config, org) return saml_config def encode_relay_state(state): params = {"state": state} return urlencode(params) def decode_relay_state(relay_state): """According to the spec, RelayState need not be a URL, yet, ``onelogin.saml2` exposes it as ``return_to -- The target URL the user should be redirected to after login``. Also, for an IdP initiated login sometimes a URL is used. """ next_url = None if relay_state: parts = urlparse(relay_state) if parts.scheme or parts.netloc or (parts.path and parts.path.startswith("/")): next_url = relay_state return next_url def build_auth(request, provider): req = prepare_django_request(request) config = build_saml_config(request, provider.app.settings, provider.app.client_id) auth = OneLogin_Saml2_Auth(req, config) return auth django-allauth-65.0.2/allauth/socialaccount/providers/saml/views.py000066400000000000000000000162521467545753200254670ustar00rootroot00000000000000import binascii import logging from django.http import ( HttpRequest, HttpResponse, HttpResponseRedirect, JsonResponse, ) from django.urls import reverse from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.csrf import csrf_exempt from onelogin.saml2.auth import OneLogin_Saml2_Settings from onelogin.saml2.errors import OneLogin_Saml2_Error from allauth.account.adapter import get_adapter as get_account_adapter from allauth.account.internal.decorators import login_not_required from allauth.core.internal import httpkit from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.providers.base.constants import ( AuthError, AuthProcess, ) from allauth.socialaccount.providers.base.views import BaseLoginView from allauth.socialaccount.sessions import LoginSession from .utils import ( build_auth, build_saml_config, decode_relay_state, get_app_or_404, ) logger = logging.getLogger(__name__) class SAMLViewMixin: def get_app(self, organization_slug): app = get_app_or_404(self.request, organization_slug) return app def get_provider(self, organization_slug): app = self.get_app(organization_slug) return app.get_provider(self.request) @method_decorator(csrf_exempt, name="dispatch") @method_decorator(login_not_required, name="dispatch") class ACSView(SAMLViewMixin, View): def dispatch(self, request, organization_slug): url = reverse( "saml_finish_acs", kwargs={"organization_slug": organization_slug}, ) response = HttpResponseRedirect(url) acs_session = LoginSession(request, "saml_acs_session", "saml-acs-session") acs_session.store.update({"request": httpkit.serialize_request(request)}) acs_session.save(response) return response acs = ACSView.as_view() @method_decorator(login_not_required, name="dispatch") class FinishACSView(SAMLViewMixin, View): def dispatch(self, request, organization_slug): provider = self.get_provider(organization_slug) acs_session = LoginSession(request, "saml_acs_session", "saml-acs-session") acs_request = None acs_request_data = acs_session.store.get("request") if acs_request_data: acs_request = httpkit.deserialize_request(acs_request_data, HttpRequest()) acs_session.delete() if not acs_request: logger.error("Unable to finish login, SAML ACS session missing") return render_authentication_error(request, provider) auth = build_auth(acs_request, provider) error_reason = None errors = [] try: # We're doing the check for a valid `InResponeTo` ourselves later on # (*) by checking if there is a matching state stashed. auth.process_response(request_id=None) except binascii.Error: errors = ["invalid_response"] error_reason = "Invalid response" except OneLogin_Saml2_Error as e: errors = ["error"] error_reason = str(e) if not errors: errors = auth.get_errors() if errors: # e.g. ['invalid_response'] error_reason = auth.get_last_error_reason() or error_reason logger.error( "Error processing SAML ACS response: %s: %s" % (", ".join(errors), error_reason) ) return render_authentication_error( request, provider, extra_context={ "saml_errors": errors, "saml_last_error_reason": error_reason, }, ) if not auth.is_authenticated(): return render_authentication_error( request, provider, error=AuthError.CANCELLED ) login = provider.sociallogin_from_response(request, auth) # (*) If we (the SP) initiated the login, there should be a matching # state. state_id = auth.get_last_response_in_response_to() if state_id: login.state = provider.unstash_redirect_state(request, state_id) else: # IdP initiated SSO reject = provider.app.settings.get("advanced", {}).get( "reject_idp_initiated_sso", True ) if reject: logger.error("IdP initiated SSO rejected") return render_authentication_error(request, provider) next_url = decode_relay_state(acs_request.POST.get("RelayState")) login.state["process"] = AuthProcess.LOGIN if next_url: login.state["next"] = next_url return complete_social_login(request, login) finish_acs = FinishACSView.as_view() @method_decorator(csrf_exempt, name="dispatch") @method_decorator(login_not_required, name="dispatch") class SLSView(SAMLViewMixin, View): def dispatch(self, request, organization_slug): provider = self.get_provider(organization_slug) auth = build_auth(self.request, provider) should_logout = request.user.is_authenticated account_adapter = get_account_adapter(request) def force_logout(): account_adapter.logout(request) redirect_to = None error_reason = None try: redirect_to = auth.process_slo( delete_session_cb=force_logout, keep_local_session=not should_logout ) except OneLogin_Saml2_Error as e: error_reason = str(e) errors = auth.get_errors() if errors: error_reason = auth.get_last_error_reason() or error_reason logger.error( "Error processing SAML SLS response: %s: %s" % (", ".join(errors), error_reason) ) resp = HttpResponse(error_reason, content_type="text/plain") resp.status_code = 400 return resp if not redirect_to: redirect_to = account_adapter.get_logout_redirect_url(request) return HttpResponseRedirect(redirect_to) sls = SLSView.as_view() @method_decorator(login_not_required, name="dispatch") class MetadataView(SAMLViewMixin, View): def dispatch(self, request, organization_slug): provider = self.get_provider(organization_slug) config = build_saml_config( self.request, provider.app.settings, organization_slug ) saml_settings = OneLogin_Saml2_Settings( settings=config, sp_validation_only=True ) metadata = saml_settings.get_sp_metadata() errors = saml_settings.validate_metadata(metadata) if len(errors) > 0: resp = JsonResponse({"errors": errors}) resp.status_code = 500 return resp return HttpResponse(content=metadata, content_type="text/xml") metadata = MetadataView.as_view() @method_decorator(login_not_required, name="dispatch") class LoginView(SAMLViewMixin, BaseLoginView): def get_provider(self): app = self.get_app(self.kwargs["organization_slug"]) return app.get_provider(self.request) login = LoginView.as_view() django-allauth-65.0.2/allauth/socialaccount/providers/sharefile/000077500000000000000000000000001467545753200247605ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/sharefile/__init__.py000066400000000000000000000000001467545753200270570ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/sharefile/provider.py000066400000000000000000000014121467545753200271620ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.sharefile.views import ( ShareFileOAuth2Adapter, ) class ShareFileAccount(ProviderAccount): pass class ShareFileProvider(OAuth2Provider): id = "sharefile" name = "ShareFile" account_class = ShareFileAccount oauth2_adapter_class = ShareFileOAuth2Adapter def extract_uid(self, data): return str(data.get("Id", "")) def extract_common_fields(self, data): return dict( email=data.get("Email", ""), username=data.get("Username", ""), name=data.get("FullName", ""), ) provider_classes = [ShareFileProvider] django-allauth-65.0.2/allauth/socialaccount/providers/sharefile/tests.py000066400000000000000000000011321467545753200264710ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import ShareFileProvider class ShareFileTests(OAuth2TestsMixin, TestCase): provider_id = ShareFileProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "Id": "123", "Email":"user.one@domain.com", "FirstName":"Name", "LastName":"Last Name", "Company":"Company", "DefaultZone": { "Id":"zoneid" } } """, ) def get_expected_to_str(self): return "user.one@domain.com" django-allauth-65.0.2/allauth/socialaccount/providers/sharefile/urls.py000066400000000000000000000002541467545753200263200ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import ShareFileProvider urlpatterns = default_urlpatterns(ShareFileProvider) django-allauth-65.0.2/allauth/socialaccount/providers/sharefile/views.py000066400000000000000000000027461467545753200265000ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class ShareFileOAuth2Adapter(OAuth2Adapter): provider_id = "sharefile" settings = app_settings.PROVIDERS.get(provider_id, {}) subdomain = settings.get("SUBDOMAIN", "secure") apicp = settings.get("APICP", "sharefile.com") provider_default_url = settings.get("DEFAULT_URL", "https://secure.sharefile.com") provider_default_api_url = "https://{}.sf-api.com".format(subdomain) provider_api_version = "v3" access_token_url = "https://{}.{}/oauth/token".format(subdomain, apicp) refresh_token_url = "https://{}.{}/oauth/token".format(subdomain, apicp) authorize_url = "{}/oauth/authorize".format(provider_default_url) profile_url = "{}/sf/{}/Users".format( provider_default_api_url, provider_api_version ) def complete_login(self, request, app, token, response): headers = {"Authorization": "Bearer {}".format(token.token)} extra_data = ( get_adapter() .get_requests_session() .get(self.profile_url, headers=headers) .json() ) return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(ShareFileOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(ShareFileOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/shopify/000077500000000000000000000000001467545753200244775ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/shopify/__init__.py000066400000000000000000000000001467545753200265760ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/shopify/provider.py000066400000000000000000000036151467545753200267100ustar00rootroot00000000000000from django.conf import settings from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.shopify.views import ShopifyOAuth2Adapter class ShopifyAccount(ProviderAccount): def get_user_data(self): return self.account.extra_data.get("shop", {}) class ShopifyProvider(OAuth2Provider): id = "shopify" name = "Shopify" account_class = ShopifyAccount oauth2_adapter_class = ShopifyOAuth2Adapter @property def is_per_user(self): grant_options = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("shopify", {}) .get("AUTH_PARAMS", {}) .get("grant_options[]", "") ) return grant_options.lower().strip() == "per-user" def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) shop = request.GET.get("shop", None) if shop: ret.update({"shop": shop}) return ret def get_default_scope(self): return ["read_orders", "read_products"] def extract_uid(self, data): if self.is_per_user: return str(data["associated_user"]["id"]) else: return str(data["shop"]["id"]) def extract_common_fields(self, data): if self.is_per_user: return dict( email=data["associated_user"]["email"], first_name=data["associated_user"]["first_name"], last_name=data["associated_user"]["last_name"], ) else: # See: https://docs.shopify.com/api/shop # Without online mode, User is only available with Shopify Plus, # email is the only common field return dict(email=data["shop"]["email"]) provider_classes = [ShopifyProvider] django-allauth-65.0.2/allauth/socialaccount/providers/shopify/tests.py000066400000000000000000000127111467545753200262150ustar00rootroot00000000000000import json from urllib.parse import parse_qs, urlparse from django.test.utils import override_settings from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .provider import ShopifyProvider class ShopifyTests(OAuth2TestsMixin, TestCase): provider_id = ShopifyProvider.id def _complete_shopify_login(self, q, resp, resp_mock, with_refresh_token): complete_url = reverse(self.provider.id + "_callback") self.assertGreater(q["redirect_uri"][0].find(complete_url), 0) response_json = self.get_login_response_json( with_refresh_token=with_refresh_token ) with mocked_response( MockedResponse(200, response_json, {"content-type": "application/json"}), resp_mock, ): resp = self.client.get( complete_url, { "code": "test", "state": q["state"][0], "shop": "test", }, ) return resp def login(self, resp_mock, process="login", with_refresh_token=True): url = ( reverse(self.provider.id + "_login") + "?" + urlencode({"process": process, "shop": "test"}) ) resp = self.client.post(url) self.assertEqual(resp.status_code, 302) p = urlparse(resp["location"]) q = parse_qs(p.query) resp = self._complete_shopify_login(q, resp, resp_mock, with_refresh_token) return resp def get_mocked_response(self): return MockedResponse( 200, """ { "shop": { "id": "1234566", "name": "Test Shop", "email": "email@example.com" } } """, ) def get_expected_to_str(self): return "email@example.com" @override_settings(SOCIALACCOUNT_PROVIDERS={"shopify": {"IS_EMBEDDED": True}}) class ShopifyEmbeddedTests(ShopifyTests): """ Shopify embedded apps (that run within an iFrame) require a JS (not server) redirect for starting the oauth2 process. See Also: https://help.shopify.com/api/sdks/embedded-app-sdk/getting-started#oauth """ def login(self, resp_mock, process="login", with_refresh_token=True): resp = self.client.post( reverse(self.provider.id + "_login") + "?" + urlencode({"process": process, "shop": "test"}), ) self.assertEqual(resp.status_code, 200) # No re-direct, JS must do it actual_content = resp.content.decode("utf8") self.assertTrue( "script" in actual_content, "Content missing script tag. [Actual: {}]".format(actual_content), ) self.assertTrue( resp.xframe_options_exempt, "Redirect JS must be allowed to run in Shopify iframe", ) self.assertTrue( "" in actual_content and "" in actual_content, "Expected standard HTML skeleton. [Actual: {}]".format(actual_content), ) p = urlparse( actual_content.split(";")[0].split('location.href = "')[1] ) q = parse_qs(p.query) resp = self._complete_shopify_login(q, resp, resp_mock, with_refresh_token) return resp @override_settings( SOCIALACCOUNT_PROVIDERS={ "shopify": {"AUTH_PARAMS": {"grant_options[]": "per-user"}} } ) class ShopifyPerUserAccessTests(ShopifyTests): """ Shopify has two access modes, offline (the default) and online/per-user. Enabling 'online' access should cause all-auth to tie the logged in Shopify user to the all-auth account (rather than the shop as a whole). See Also: https://help.shopify.com/api/getting-started/authentication/ oauth#api-access-modes """ def get_login_response_json(self, with_refresh_token=True): response_data = { "access_token": "testac", "scope": "write_orders,read_customers", "expires_in": 86399, "associated_user_scope": "write_orders", "associated_user": { "id": 902541635, "first_name": "Jon", "last_name": "Smith", "email": "jon@example.com", "account_owner": True, }, } if with_refresh_token: response_data["refresh_token"] = "testrf" return json.dumps(response_data) @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=True, SOCIALACCOUNT_EMAIL_REQUIRED=True, ACCOUNT_EMAIL_REQUIRED=True, ) def test_associated_user(self): resp_mocks = self.get_mocked_response() resp = self.login(resp_mocks) self.assertRedirects(resp, "/accounts/profile/", fetch_redirect_response=False) social_account = SocialAccount.objects.filter( provider=self.provider.id, uid=902541635, ).first() self.assertIsNotNone(social_account) self.assertTrue("associated_user" in social_account.extra_data) self.assertEqual(social_account.user.email, "jon@example.com") self.assertEqual(social_account.user.first_name, "Jon") self.assertEqual(social_account.user.last_name, "Smith") django-allauth-65.0.2/allauth/socialaccount/providers/shopify/urls.py000066400000000000000000000002501467545753200260330ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import ShopifyProvider urlpatterns = default_urlpatterns(ShopifyProvider) django-allauth-65.0.2/allauth/socialaccount/providers/shopify/views.py000066400000000000000000000070101467545753200262040ustar00rootroot00000000000000import re from django.conf import settings from django.http import HttpResponse, HttpResponseBadRequest from allauth.core.exceptions import ImmediateHttpResponse from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class ShopifyOAuth2Adapter(OAuth2Adapter): provider_id = "shopify" scope_delimiter = "," def _shop_domain(self): shop = self.request.GET.get("shop", "") if "." not in shop: shop = "{}.myshopify.com".format(shop) # Ensure the provided hostname parameter is a valid hostname, # ends with myshopify.com, and does not contain characters # other than letters (a-z), numbers (0-9), dots, and hyphens. if not re.match(r"^[a-z0-9-]+\.myshopify\.com$", shop): raise ImmediateHttpResponse( HttpResponseBadRequest("Invalid `shop` parameter") ) return shop def _shop_url(self, path): shop = self._shop_domain() return "https://{}{}".format(shop, path) @property def access_token_url(self): return self._shop_url("/admin/oauth/access_token") @property def authorize_url(self): return self._shop_url("/admin/oauth/authorize") @property def profile_url(self): return self._shop_url("/admin/shop.json") def complete_login(self, request, app, token, **kwargs): headers = {"X-Shopify-Access-Token": "{token}".format(token=token.token)} response = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = response.json() associated_user = kwargs["response"].get("associated_user") if associated_user: extra_data["associated_user"] = associated_user return self.get_provider().sociallogin_from_response(request, extra_data) class ShopifyOAuth2LoginView(OAuth2LoginView): def dispatch(self, request, *args, **kwargs): is_embedded = ( getattr(settings, "SOCIALACCOUNT_PROVIDERS", {}) .get("shopify", {}) .get("IS_EMBEDDED", False) ) if is_embedded: # TODO: This bypasses LOGIN_ON_GET, but: # # The Embedded App SDK (EASDK) and backwards compatibility layer # are being removed from Shopify on January 1, 2022. # # So this needs to be dropped/revisitted anyway. response = super().dispatch(request, *args, **kwargs) """ Shopify embedded apps (that run within an iFrame) require a JS (not server) redirect for starting the oauth2 process. See Also: https://help.shopify.com/api/sdks/embedded-app-sdk/getting-started#oauth """ js = "".join( ( "" '", ) ) response = HttpResponse(content=js) # Because this view will be within shopify's iframe response.xframe_options_exempt = True return response return super().dispatch(request, *args, **kwargs) oauth2_login = ShopifyOAuth2LoginView.adapter_view(ShopifyOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(ShopifyOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/slack/000077500000000000000000000000001467545753200241135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/slack/__init__.py000066400000000000000000000000001467545753200262120ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/slack/models.py000066400000000000000000000000001467545753200257360ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/slack/provider.py000066400000000000000000000022021467545753200263130ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.slack.views import SlackOAuth2Adapter class SlackAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("user", {}).get("image_192") class SlackProvider(OAuth2Provider): id = "slack" name = "Slack" account_class = SlackAccount oauth2_adapter_class = SlackOAuth2Adapter def extract_uid(self, data): team_id = data.get("https://slack.com/team_id") user_id = data.get("https://slack.com/user_id") if not (team_id and user_id): team_id = data.get("team").get("id") user_id = data.get("user").get("id") return "%s_%s" % ( str(team_id), str(user_id), ) def extract_common_fields(self, data): user = data.get("user", {}) return {"name": user.get("name"), "email": user.get("email", None)} def get_default_scope(self): return ["openid", "profile", "email"] provider_classes = [SlackProvider] django-allauth-65.0.2/allauth/socialaccount/providers/slack/tests.py000066400000000000000000000016421467545753200256320ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import SlackProvider class SlackOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = SlackProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "ok": true, "sub": "U0R7JM", "https://slack.com/user_id": "U0R7JM", "https://slack.com/team_id": "T0R7GR", "email": "krane@slack-corp.com", "email_verified": true, "date_email_verified": 1622128723, "name": "krane", "picture": "https://secure.gravatar.com/....png", "given_name": "Bront", "family_name": "Labradoodle", "locale": "en-US", "https://slack.com/team_name": "kraneflannel", "https://slack.com/team_domain": "kraneflannel" }""", ) # noqa def get_expected_to_str(self): return "krane@slack-corp.com" django-allauth-65.0.2/allauth/socialaccount/providers/slack/urls.py000066400000000000000000000002441467545753200254520ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import SlackProvider urlpatterns = default_urlpatterns(SlackProvider) django-allauth-65.0.2/allauth/socialaccount/providers/slack/views.py000066400000000000000000000022131467545753200256200ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class SlackOAuth2Adapter(OAuth2Adapter): provider_id = "slack" access_token_url = "https://slack.com/api/openid.connect.token" authorize_url = "https://slack.com//openid/connect/authorize" identity_url = "https://slack.com/api/openid.connect.userInfo" def complete_login(self, request, app, token, **kwargs): extra_data = self.get_data(token.token) return self.get_provider().sociallogin_from_response(request, extra_data) def get_data(self, token): # Verify the user first hed = {"Authorization": "Bearer " + token} resp = get_adapter().get_requests_session().get(self.identity_url, headers=hed) resp = resp.json() if not resp.get("ok"): raise OAuth2Error() return resp oauth2_login = OAuth2LoginView.adapter_view(SlackOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(SlackOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/000077500000000000000000000000001467545753200246175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/__init__.py000066400000000000000000000000001467545753200267160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/constants.py000066400000000000000000000004071467545753200272060ustar00rootroot00000000000000PROVIDER_ID = "snapchat" class Scope: EXTERNAL_ID = "https://auth.snapchat.com/oauth2/api/user.external_id" DISPLAY_NAME = "https://auth.snapchat.com/oauth2/api/user.display_name" BITMOJI = "https://auth.snapchat.com/oauth2/api/user.bitmoji.avatar" django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/models.py000066400000000000000000000000001467545753200264420ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/provider.py000066400000000000000000000020001467545753200270130ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.snapchat.constants import ( PROVIDER_ID, Scope, ) from allauth.socialaccount.providers.snapchat.views import ( SnapchatOAuth2Adapter, ) class SnapchatAccount(ProviderAccount): def get_user_data(self): return self.account.extra_data.get("data", {}).get("me", {}) class SnapchatProvider(OAuth2Provider): id = PROVIDER_ID name = "Snapchat" account_class = SnapchatAccount oauth2_adapter_class = SnapchatOAuth2Adapter def get_default_scope(self): scope = [Scope.EXTERNAL_ID, Scope.DISPLAY_NAME] return scope def extract_uid(self, data): return str(data.get("data").get("me").get("externalId")) def extract_common_fields(self, data): user = data.get("data", {}).get("me") return {"name": user.get("displayName")} provider_classes = [SnapchatProvider] django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/tests.py000066400000000000000000000020641467545753200263350ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import SnapchatProvider class SnapchatOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = SnapchatProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "data":{ "me":{ "externalId":"CAESIPiRBp0e5gLDq7VVurQ3rVdmdbqxpOJWynjyBL/xlo0w", "displayName":"Karun Shrestha", "bitmoji":{ "avatar":"https://sdk.bitmoji.com/render/panel/336d1e96-9055-4818-81aa-adde45ec030f-3aBXH5B0ZPCr~grPTZScjprXRT2RkU90oSd7X_PjDFFnBe3wuFkD1R-v1.png?transparent=1&palette=1", "id":"3aBXH5B0ZPCr~grPTZScjprXRT2RkU90oSd7X_PjDFFnBe3wuFkD1R" } } }, "errors":[] }""", ) # noqa def get_expected_to_str(self): return "Karun Shrestha" django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/urls.py000066400000000000000000000002521467545753200261550ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import SnapchatProvider urlpatterns = default_urlpatterns(SnapchatProvider) django-allauth-65.0.2/allauth/socialaccount/providers/snapchat/views.py000066400000000000000000000036351467545753200263350ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from allauth.socialaccount.providers.snapchat.constants import ( PROVIDER_ID, Scope, ) class SnapchatOAuth2Adapter(OAuth2Adapter): provider_id = PROVIDER_ID access_token_url = "https://accounts.snapchat.com/accounts/oauth2/token" authorize_url = "https://accounts.snapchat.com/accounts/oauth2/auth" identity_url = "https://api.snapkit.com/v1/me" def complete_login(self, request, app, token, **kwargs): extra_data = self.get_data(token.token) return self.get_provider().sociallogin_from_response(request, extra_data) def get_data(self, token): settings = app_settings.PROVIDERS.get(self.provider_id, {}) provider_scope = settings.get( "SCOPE", "['https://auth.snapchat.com/oauth2/api/user.external_id', 'https://auth.snapchat.com/oauth2/api/user.display_name']", ) hed = { "Authorization": "Bearer " + token, "Content-Type": "application/json;charset=UTF-8", } if Scope.BITMOJI in provider_scope: data = {"query": "{ me { externalId displayName bitmoji { avatar id } } }"} else: data = {"query": "{ me { externalId displayName } }"} resp = ( get_adapter() .get_requests_session() .post(self.identity_url, headers=hed, json=data) ) resp.raise_for_status() resp = resp.json() if not resp.get("data"): raise OAuth2Error() return resp oauth2_login = OAuth2LoginView.adapter_view(SnapchatOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(SnapchatOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/soundcloud/000077500000000000000000000000001467545753200251755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/soundcloud/__init__.py000066400000000000000000000000001467545753200272740ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/soundcloud/provider.py000066400000000000000000000016521467545753200274050ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.soundcloud.views import ( SoundCloudOAuth2Adapter, ) class SoundCloudAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("permalink_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") class SoundCloudProvider(OAuth2Provider): id = "soundcloud" name = "SoundCloud" account_class = SoundCloudAccount oauth2_adapter_class = SoundCloudOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( name=data.get("full_name"), username=data.get("username"), email=data.get("email"), ) provider_classes = [SoundCloudProvider] django-allauth-65.0.2/allauth/socialaccount/providers/soundcloud/tests.py000066400000000000000000000026151467545753200267150ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import SoundCloudProvider class SoundCloudTests(OAuth2TestsMixin, TestCase): provider_id = SoundCloudProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "website": null, "myspace_name": null, "public_favorites_count": 0, "followings_count": 1, "full_name": "", "id": 22341947, "city": null, "track_count": 0, "playlist_count": 0, "discogs_name": null, "private_tracks_count": 0, "followers_count": 0, "online": true, "username": "user187631676", "description": null, "kind": "user", "website_title": null, "primary_email_confirmed": false, "permalink_url": "http://soundcloud.com/user187631676", "private_playlists_count": 0, "permalink": "user187631676", "country": null, "uri": "https://api.soundcloud.com/users/22341947", "avatar_url": "https://a1.sndcdn.com/images/default_avatar_large.png?4b4189b", "plan": "Free" }""", ) def get_expected_to_str(self): return "user187631676" django-allauth-65.0.2/allauth/socialaccount/providers/soundcloud/urls.py000066400000000000000000000002561467545753200265370ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import SoundCloudProvider urlpatterns = default_urlpatterns(SoundCloudProvider) django-allauth-65.0.2/allauth/socialaccount/providers/soundcloud/views.py000066400000000000000000000016231467545753200267060ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class SoundCloudOAuth2Adapter(OAuth2Adapter): provider_id = "soundcloud" access_token_url = "https://api.soundcloud.com/oauth2/token" authorize_url = "https://soundcloud.com/connect" profile_url = "https://api.soundcloud.com/me.json" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"oauth_token": token.token}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(SoundCloudOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(SoundCloudOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/spotify/000077500000000000000000000000001467545753200245135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/spotify/__init__.py000066400000000000000000000000001467545753200266120ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/spotify/provider.py000066400000000000000000000021511467545753200267160ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.spotify.views import SpotifyOAuth2Adapter class SpotifyAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("external_urls").get("spotify") def get_avatar_url(self): try: return self.account.extra_data.get("images")[0].get("url") except IndexError: return None class SpotifyOAuth2Provider(OAuth2Provider): id = "spotify" name = "Spotify" account_class = SpotifyAccount oauth2_adapter_class = SpotifyOAuth2Adapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict(name=data.get("display_name"), email=data.get("email")) def get_default_scope(self): scope = [] if app_settings.QUERY_EMAIL: scope.append("user-read-email") return scope provider_classes = [SpotifyOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/spotify/tests.py000066400000000000000000000023401467545753200262260ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import SpotifyOAuth2Provider class SpotifyOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = SpotifyOAuth2Provider.id def get_mocked_response(self): return MockedResponse( 200, """{ "birthdate": "1937-06-01", "country": "SE", "display_name": "JM Wizzler", "email": "email@example.com", "external_urls": { "spotify": "https://open.spotify.com/user/wizzler" }, "followers" : { "href" : null, "total" : 3829 }, "href": "https://api.spotify.com/v1/users/wizzler", "id": "wizzler", "images": [ { "height": null, "url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-frc3/t1.0-1/1970403_10152215092574354_1798272330_n.jpg", "width": null } ], "product": "premium", "type": "user", "uri": "spotify:user:wizzler" }""", ) # noqa def get_expected_to_str(self): return "email@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/spotify/urls.py000066400000000000000000000002631467545753200260530ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import SpotifyOAuth2Provider urlpatterns = default_urlpatterns(SpotifyOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/spotify/views.py000066400000000000000000000015651467545753200262310ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class SpotifyOAuth2Adapter(OAuth2Adapter): provider_id = "spotify" access_token_url = "https://accounts.spotify.com/api/token" authorize_url = "https://accounts.spotify.com/authorize" profile_url = "https://api.spotify.com/v1/me" def complete_login(self, request, app, token, **kwargs): extra_data = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token}) ) return self.get_provider().sociallogin_from_response(request, extra_data.json()) oauth_login = OAuth2LoginView.adapter_view(SpotifyOAuth2Adapter) oauth_callback = OAuth2CallbackView.adapter_view(SpotifyOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/stackexchange/000077500000000000000000000000001467545753200256265ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/stackexchange/__init__.py000066400000000000000000000000001467545753200277250ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/stackexchange/provider.py000066400000000000000000000022041467545753200300300ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.stackexchange.views import ( StackExchangeOAuth2Adapter, ) class StackExchangeAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("html_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") class StackExchangeProvider(OAuth2Provider): id = "stackexchange" name = "Stack Exchange" account_class = StackExchangeAccount oauth2_adapter_class = StackExchangeOAuth2Adapter def get_site(self): settings = self.get_settings() return settings.get("SITE", "stackoverflow") def extract_uid(self, data): # `user_id` varies if you use the same account for # e.g. StackOverflow and ServerFault. Therefore, we pick # `account_id`. uid = str(data["account_id"]) return uid def extract_common_fields(self, data): return dict(username=data.get("display_name")) provider_classes = [StackExchangeProvider] django-allauth-65.0.2/allauth/socialaccount/providers/stackexchange/tests.py000066400000000000000000000031041467545753200273400ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import StackExchangeProvider class StackExchangeTests(OAuth2TestsMixin, TestCase): provider_id = StackExchangeProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "has_more": false, "items": [ { "is_employee": false, "last_access_date": 1356200390, "display_name": "pennersr", "account_id": 291652, "badge_counts": { "bronze": 2, "silver": 2, "gold": 0 }, "last_modified_date": 1356199552, "profile_image": "http://www.gravatar.com/avatar/053d648486d567d3143d6bad8df8cfeb?d=identicon&r=PG", "user_type": "registered", "creation_date": 1296223711, "reputation_change_quarter": 148, "reputation_change_year": 378, "reputation": 504, "link": "http://stackoverflow.com/users/593944/pennersr", "reputation_change_week": 0, "user_id": 593944, "reputation_change_month": 10, "reputation_change_day": 0 } ], "quota_max": 10000, "quota_remaining": 9999 }""", ) # noqa def get_expected_to_str(self): return "pennersr" django-allauth-65.0.2/allauth/socialaccount/providers/stackexchange/urls.py000066400000000000000000000002641467545753200271670ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import StackExchangeProvider urlpatterns = default_urlpatterns(StackExchangeProvider) django-allauth-65.0.2/allauth/socialaccount/providers/stackexchange/views.py000066400000000000000000000021531467545753200273360ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class StackExchangeOAuth2Adapter(OAuth2Adapter): provider_id = "stackexchange" access_token_url = "https://stackexchange.com/oauth/access_token" authorize_url = "https://stackexchange.com/oauth" profile_url = "https://api.stackexchange.com/2.1/me" def complete_login(self, request, app, token, **kwargs): provider = self.get_provider() site = provider.get_site() resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token, "key": app.key, "site": site}, ) ) resp.raise_for_status() extra_data = resp.json()["items"][0] return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(StackExchangeOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(StackExchangeOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/steam/000077500000000000000000000000001467545753200241275ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/steam/__init__.py000066400000000000000000000000001467545753200262260ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/steam/models.py000066400000000000000000000000001467545753200257520ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/steam/provider.py000066400000000000000000000062341467545753200263400ustar00rootroot00000000000000from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.openid.provider import ( OpenIDAccount, OpenIDProvider, ) if "allauth.socialaccount.providers.openid" not in settings.INSTALLED_APPS: raise ImproperlyConfigured( "The steam provider requires 'allauth.socialaccount.providers.openid' to be installed" ) class SteamAccount(OpenIDAccount): def to_str(self): dflt = super(SteamAccount, self).to_str() return self.account.extra_data.get("personaname", dflt) def get_profile_url(self): return self.account.extra_data.get("profileurl") def get_avatar_url(self): return ( self.account.extra_data.get("avatarfull") or self.account.extra_data.get("avatarmedium") or self.account.extra_data.get("avatar") ) def extract_steam_id(url): prefix = "https://steamcommunity.com/openid/id/" if not url.startswith(prefix): raise ValueError(url) return url[len(prefix) :] def request_steam_account_summary(api_key, steam_id): api_base = "https://api.steampowered.com/" method = "ISteamUser/GetPlayerSummaries/v0002/" params = {"key": api_key, "steamids": steam_id} resp = get_adapter().get_requests_session().get(api_base + method, params=params) resp.raise_for_status() data = resp.json() playerlist = data.get("response", {}).get("players", []) return playerlist[0] if playerlist else {"steamid": steam_id} class SteamOpenIDProvider(OpenIDProvider): id = "steam" name = "Steam" account_class = SteamAccount uses_apps = True def __init__(self, request, app=None): if app is None: app = get_adapter().get_app(request, self.id) super().__init__(request, app=app) def get_login_url(self, request, **kwargs): url = reverse("steam_login") if kwargs: url += "?" + urlencode(kwargs) return url def sociallogin_from_response(self, request, response): steam_id = extract_steam_id(response.identity_url) steam_api_key = self.app.secret response._extra = request_steam_account_summary(steam_api_key, steam_id) return super(SteamOpenIDProvider, self).sociallogin_from_response( request, response ) def extract_uid(self, response): return response._extra["steamid"] def extract_extra_data(self, response): return response._extra.copy() def extract_common_fields(self, response): full_name = response._extra.get("realname", "").strip() if full_name.count(" ") == 1: first_name, last_name = full_name.split() else: first_name, last_name = full_name, "" username = response._extra.get("personaname", "") return { "username": username or response._extra["steamid"], "first_name": first_name, "last_name": last_name, "full_name": full_name, } provider_classes = [SteamOpenIDProvider] django-allauth-65.0.2/allauth/socialaccount/providers/steam/urls.py000066400000000000000000000003211467545753200254620ustar00rootroot00000000000000from django.urls import path from . import views urlpatterns = [ path("steam/login/", views.steam_login, name="steam_login"), path("steam/callback/", views.steam_callback, name="steam_callback"), ] django-allauth-65.0.2/allauth/socialaccount/providers/steam/views.py000066400000000000000000000021121467545753200256320ustar00rootroot00000000000000""" OpenID Adapter for Steam The Steam login API is simple OpenID but requires extra API calls for basic resources such as usernames. Resources: * Steam Web API Documentation https://steamcommunity.com/dev * Steam Partner API documentation https://partner.steamgames.com/doc/features/auth#website """ from django.urls import reverse from allauth.socialaccount.providers.openid.views import ( OpenIDCallbackView, OpenIDLoginView, ) from .provider import SteamOpenIDProvider STEAM_OPENID_URL = "https://steamcommunity.com/openid" class SteamOpenIDLoginView(OpenIDLoginView): provider_class = SteamOpenIDProvider def get_form(self): items = dict(list(self.request.GET.items()) + list(self.request.POST.items())) items["openid"] = STEAM_OPENID_URL return self.form_class(items) def get_callback_url(self): return reverse(steam_callback) class SteamOpenIDCallbackView(OpenIDCallbackView): provider_class = SteamOpenIDProvider steam_login = SteamOpenIDLoginView.as_view() steam_callback = SteamOpenIDCallbackView.as_view() django-allauth-65.0.2/allauth/socialaccount/providers/stocktwits/000077500000000000000000000000001467545753200252345ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/stocktwits/__init__.py000066400000000000000000000000001467545753200273330ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/stocktwits/provider.py000066400000000000000000000015771467545753200274520ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.stocktwits.views import ( StocktwitsOAuth2Adapter, ) class StocktwitsAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("user", {}).get("avatar_url_ssl") def get_user_data(self): return self.account.extra_data.get("user", {}) class StocktwitsProvider(OAuth2Provider): id = "stocktwits" name = "Stocktwits" account_class = StocktwitsAccount oauth2_adapter_class = StocktwitsOAuth2Adapter def extract_uid(self, data): return str(data["user"]["id"]) def extract_common_fields(self, data): return dict( full_name=data.get("user", {}).get("name"), ) provider_classes = [StocktwitsProvider] django-allauth-65.0.2/allauth/socialaccount/providers/stocktwits/tests.py000066400000000000000000000014431467545753200267520ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import StocktwitsProvider class StocktwitsTests(OAuth2TestsMixin, TestCase): provider_id = StocktwitsProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "response": { "status": 200 }, "user": { "id": 3, "username": "zerobeta", "name": "Justin Paterno", "avatar_url": "http://avatars.stocktwits.com/images/default_avatar_thumb.jpg", "avatar_url_ssl": "https://s3.amazonaws.com/st-avatars/images/default_avatar_thumb.jpg", "identity": "Official", "classification": [ "ir" ] } } """, ) # noqa def get_expected_to_str(self): return "zerobeta" django-allauth-65.0.2/allauth/socialaccount/providers/stocktwits/urls.py000066400000000000000000000002561467545753200265760ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import StocktwitsProvider urlpatterns = default_urlpatterns(StocktwitsProvider) django-allauth-65.0.2/allauth/socialaccount/providers/stocktwits/views.py000066400000000000000000000020431467545753200267420ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class StocktwitsOAuth2Adapter(OAuth2Adapter): provider_id = "stocktwits" access_token_url = "https://api.stocktwits.com/api/2/oauth/token" authorize_url = "https://api.stocktwits.com/api/2/oauth/authorize" profile_url = "https://api.stocktwits.com/api/2/streams/user/{user}.json" scope_delimiter = "," def complete_login(self, request, app, token, **kwargs): user_id = kwargs.get("response").get("user_id") resp = ( get_adapter() .get_requests_session() .get(self.profile_url.format(user=user_id)) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(StocktwitsOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(StocktwitsOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/strava/000077500000000000000000000000001467545753200243165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/strava/__init__.py000066400000000000000000000000001467545753200264150ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/strava/provider.py000066400000000000000000000027151467545753200265270ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.strava.views import StravaOAuth2Adapter class StravaAccount(ProviderAccount): def get_profile_url(self): id = self.account.extra_data.get("id") if id: return "https://www.strava.com/athletes/{}".format(id) return None def get_avatar_url(self): avatar = self.account.extra_data.get("profile") if avatar and avatar != "avatar/athlete/large.png": return avatar return None class StravaProvider(OAuth2Provider): id = "strava" name = "Strava" account_class = StravaAccount oauth2_adapter_class = StravaOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): extra_common = super(StravaProvider, self).extract_common_fields(data) firstname = data.get("firstname") lastname = data.get("lastname") name = " ".join(part for part in (firstname, lastname) if part) extra_common.update( username=data.get("username"), email=data.get("email"), first_name=firstname, last_name=lastname, name=name.strip(), ) return extra_common def get_default_scope(self): return ["read,activity:read"] provider_classes = [StravaProvider] django-allauth-65.0.2/allauth/socialaccount/providers/strava/tests.py000066400000000000000000000065601467545753200260410ustar00rootroot00000000000000from django.contrib.auth.models import User from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import StravaProvider class StravaTests(OAuth2TestsMixin, TestCase): provider_id = StravaProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "id": 32641234, "username": null, "resource_state": 2, "firstname": "georges", "lastname": "camembert", "city": "London", "state": "England", "country": "United Kingdom", "sex": "M", "premium": false, "summit": false, "created_at": "2017-07-12T12:42:52Z", "updated_at": "2017-10-21T11:01:23Z", "badge_type_id": 0, "profile_medium": "avatar/athlete/medium.png", "profile": "avatar/athlete/large.png", "friend": null, "follower": null, "email": "bill@example.com" }""", ) # noqa def get_expected_to_str(self): return "bill@example.com" def get_mocked_response_avatar_invalid_id(self): """Profile including realistic avatar URL user ID set to 0 to test edge case where id would be missing""" return MockedResponse( 200, """{ "id": 0, "username": null, "resource_state": 2, "firstname": "georges", "lastname": "camembert", "city": "London", "state": "England", "country": "United Kingdom", "sex": "M", "premium": false, "summit": false, "created_at": "2017-07-12T12:42:52Z", "updated_at": "2017-10-21T11:01:23Z", "badge_type_id": 0, "profile_medium": "https://cloudfront.net/1/medium.jpg", "profile": "https://cloudfront.net/1/large.jpg", "friend": null, "follower": null, "email": "bill@example.com" }""", ) # noqa def test_valid_avatar(self): """test response with Avatar URL""" self.login(self.get_mocked_response_avatar_invalid_id()) user = User.objects.get(email="bill@example.com") soc_acc = SocialAccount.objects.filter( user=user, provider=self.provider.id ).get() provider_account = soc_acc.get_provider_account() self.assertEqual( provider_account.get_avatar_url(), "https://cloudfront.net/1/large.jpg", ) self.assertIsNone(provider_account.get_profile_url()) def get_login_response_json(self, with_refresh_token=True): rt = "" if with_refresh_token: rt = ',"refresh_token": "testrf"' return ( """{ "uid":"weibo", "access_token":"testac", "livemode": false, "token_type": "bearer", "strava_publishable_key": "pk_test_someteskey", "strava_user_id": "acct_sometestid", "scope": "read_write" %s }""" % rt ) django-allauth-65.0.2/allauth/socialaccount/providers/strava/urls.py000066400000000000000000000002461467545753200256570ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import StravaProvider urlpatterns = default_urlpatterns(StravaProvider) django-allauth-65.0.2/allauth/socialaccount/providers/strava/views.py000066400000000000000000000016411467545753200260270ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class StravaOAuth2Adapter(OAuth2Adapter): provider_id = "strava" access_token_url = "https://www.strava.com/oauth/token" authorize_url = "https://www.strava.com/oauth/authorize" profile_url = "https://www.strava.com/api/v3/athlete" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(StravaOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(StravaOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/stripe/000077500000000000000000000000001467545753200243245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/stripe/__init__.py000066400000000000000000000000001467545753200264230ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/stripe/provider.py000066400000000000000000000017751467545753200265420ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.stripe.views import StripeOAuth2Adapter class StripeAccount(ProviderAccount): def to_str(self): default = super(StripeAccount, self).to_str() email = self.account.extra_data.get("email") business = self.account.extra_data.get("business_name") if business: return "%s (%s)" % (email or default, business) else: return email or default class StripeProvider(OAuth2Provider): id = "stripe" name = "Stripe" account_class = StripeAccount oauth2_adapter_class = StripeOAuth2Adapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict(name=data.get("display_name"), email=data.get("email")) def get_default_scope(self): return ["read_only"] provider_classes = [StripeProvider] django-allauth-65.0.2/allauth/socialaccount/providers/stripe/tests.py000066400000000000000000000031601467545753200260400ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import StripeProvider class StripeTests(OAuth2TestsMixin, TestCase): provider_id = StripeProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "id": "acct_sometestid", "object": "account", "business_logo": null, "business_name": null, "business_url": "example.com", "charges_enabled": true, "country": "SE", "currencies_supported": [ "usd", "eur", "sek" ], "default_currency": "eur", "details_submitted": true, "display_name": "Test", "email": "test@example.com", "managed": false, "metadata": {}, "statement_descriptor": "TEST.COM", "support_phone": "+460123456789", "timezone": "Europe/Stockholm", "transfers_enabled": true }""", ) def get_expected_to_str(self): return "test@example.com" def get_login_response_json(self, with_refresh_token=True): rt = "" if with_refresh_token: rt = ',"refresh_token": "testrf"' return ( """{ "uid":"weibo", "access_token":"testac", "livemode": false, "token_type": "bearer", "stripe_publishable_key": "pk_test_someteskey", "stripe_user_id": "acct_sometestid", "scope": "read_write" %s }""" % rt ) django-allauth-65.0.2/allauth/socialaccount/providers/stripe/urls.py000066400000000000000000000002461467545753200256650ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import StripeProvider urlpatterns = default_urlpatterns(StripeProvider) django-allauth-65.0.2/allauth/socialaccount/providers/stripe/views.py000066400000000000000000000017561467545753200260440ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class StripeOAuth2Adapter(OAuth2Adapter): provider_id = "stripe" access_token_url = "https://connect.stripe.com/oauth/token" authorize_url = "https://connect.stripe.com/oauth/authorize" profile_url = "https://api.stripe.com/v1/accounts/%s" def complete_login(self, request, app, token, response, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter() .get_requests_session() .get(self.profile_url % response.get("stripe_user_id"), headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(StripeOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(StripeOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/telegram/000077500000000000000000000000001467545753200246165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/__init__.py000066400000000000000000000000001467545753200267150ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/provider.py000066400000000000000000000040651467545753200270270ustar00rootroot00000000000000from django.http import HttpResponseRedirect from django.urls import reverse from django.utils.http import urlencode from allauth.socialaccount.providers.base import Provider, ProviderAccount class TelegramAccount(ProviderAccount): pass class TelegramProvider(Provider): id = "telegram" name = "Telegram" account_class = TelegramAccount supports_redirect = True def get_login_url(self, request, **kwargs): url = reverse("telegram_login") if kwargs: url = url + "?" + urlencode(kwargs) return url def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): ret = {} if data.get("first_name"): ret["first_name"] = data.get("first_name") if data.get("last_name"): ret["last_name"] = data.get("last_name") if data.get("username"): ret["username"] = data.get("username") return ret def get_auth_date_validity(self): auth_date_validity = 30 settings = self.get_settings() if "AUTH_PARAMS" in settings: auth_date_validity = settings.get("AUTH_PARAMS").get( "auth_date_validity", auth_date_validity ) auth_date_validity = self.app.settings.get( "auth_date_validity", auth_date_validity ) return auth_date_validity def redirect(self, request, process, next_url=None, data=None, **kwargs): state = self.stash_redirect_state(request, process, next_url, data, **kwargs) return_to = request.build_absolute_uri( reverse("telegram_callback") + "?" + urlencode({"state": state}) ) url = "https://oauth.telegram.org/auth?" + urlencode( { "origin": request.build_absolute_uri("/"), "bot_id": self.app.client_id, "request_access": "write", "embed": "0", "return_to": return_to, } ) return HttpResponseRedirect(url) provider_classes = [TelegramProvider] django-allauth-65.0.2/allauth/socialaccount/providers/telegram/static/000077500000000000000000000000001467545753200261055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/static/telegram/000077500000000000000000000000001467545753200277055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/static/telegram/js/000077500000000000000000000000001467545753200303215ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/static/telegram/js/telegram.js000066400000000000000000000007301467545753200324570ustar00rootroot00000000000000/* global document, window */ (function () { 'use strict' const f = document.createElement('form') f.method = 'POST' f.action = '' const fragment = window.location.hash.substr(1) const fragmentParams = new URLSearchParams(fragment) for (const param of fragmentParams) { const d = document.createElement('input') d.type = 'hidden' d.name = param[0] d.value = param[1] f.appendChild(d) } document.body.appendChild(f) f.submit() })() django-allauth-65.0.2/allauth/socialaccount/providers/telegram/templates/000077500000000000000000000000001467545753200266145ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/templates/telegram/000077500000000000000000000000001467545753200304145ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/telegram/templates/telegram/callback.html000066400000000000000000000001771467545753200330430ustar00rootroot00000000000000{% load static %} django-allauth-65.0.2/allauth/socialaccount/providers/telegram/tests.py000066400000000000000000000032751467545753200263410ustar00rootroot00000000000000import base64 import json from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.socialaccount.models import SocialAccount @pytest.fixture def telegram_app(settings): settings.SOCIALACCOUNT_PROVIDERS = { "telegram": { "APPS": [ { "client_id": "123", } ] } } def test_login(client, db, telegram_app): resp = client.post(reverse("telegram_login")) assert resp.status_code == 302 assert resp["location"].startswith( "https://oauth.telegram.org/auth?origin=http%3A%2F%2Ftestserver%2F&bot_id=123&request_access=write&embed=0&return_to=http%3A%2F%2Ftestserver%2Faccounts%2Ftelegram%2Flogin%2Fcallback%2F%3Fstate%3D" ) def test_callback_get(client, db, telegram_app): resp = client.get(reverse("telegram_callback")) assert resp.status_code == 200 assertTemplateUsed(resp, "telegram/callback.html") def test_callback(client, db, telegram_app, sociallogin_setup_state): state = sociallogin_setup_state(client) auth_result = ( base64.b64encode( json.dumps( { "id": "123", "hash": "0744ab643757850e82fa8b4ac35978dca287c81df6a9829032d868c7f90e3b99", "auth_date": 2342342342, } ).encode("utf8") ) .decode("ascii") .replace("=", "") ) post_data = { "tgAuthResult": auth_result, } resp = client.post(reverse("telegram_callback") + f"?state={state}", post_data) assert resp.status_code == 302 assert SocialAccount.objects.filter(uid="123").exists() django-allauth-65.0.2/allauth/socialaccount/providers/telegram/urls.py000066400000000000000000000003271467545753200261570ustar00rootroot00000000000000from django.urls import path from . import views urlpatterns = [ path("telegram/login/", views.login, name="telegram_login"), path("telegram/login/callback/", views.callback, name="telegram_callback"), ] django-allauth-65.0.2/allauth/socialaccount/providers/telegram/views.py000066400000000000000000000054511467545753200263320ustar00rootroot00000000000000import base64 import binascii import hashlib import hmac import json import time from django.shortcuts import render from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.csrf import csrf_exempt from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.helpers import ( complete_social_login, render_authentication_error, ) from allauth.socialaccount.providers.base.views import BaseLoginView from allauth.socialaccount.providers.telegram.provider import TelegramProvider @method_decorator(login_not_required, name="dispatch") class LoginView(BaseLoginView): provider_id = TelegramProvider.id login = LoginView.as_view() @method_decorator(csrf_exempt, name="dispatch") @method_decorator(login_not_required, name="dispatch") class CallbackView(View): def get(self, request): return render(request, "telegram/callback.html") def post(self, request): adapter = get_adapter() provider = adapter.get_provider(request, TelegramProvider.id) state_id = request.GET.get("state") if not state_id: return render_authentication_error( request, provider=provider, ) try: result = request.POST.get("tgAuthResult") padding = "=" * (4 - (len(result) % 4)) data = json.loads(base64.b64decode(result + padding)) if not isinstance(data, dict) or "hash" not in data: raise ValueError("Invalid tgAuthResult") except (binascii.Error, json.JSONDecodeError, ValueError) as e: return render_authentication_error( request, provider=provider, exception=e, extra_context={"state_id": state_id}, ) hash = data.pop("hash") payload = "\n".join(sorted(["{}={}".format(k, v) for k, v in data.items()])) token = provider.app.secret token_sha256 = hashlib.sha256(token.encode()).digest() expected_hash = hmac.new( token_sha256, payload.encode(), hashlib.sha256 ).hexdigest() auth_date = int(data.pop("auth_date")) auth_date_validity = provider.get_auth_date_validity() if hash != expected_hash or time.time() - auth_date > auth_date_validity: return render_authentication_error( request, provider=provider, extra_context={"response": data, "state_id": state_id}, ) login = provider.sociallogin_from_response(request, data) login.state = provider.unstash_redirect_state(request, state_id) return complete_social_login(request, login) callback = CallbackView.as_view() django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/000077500000000000000000000000001467545753200243235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/__init__.py000066400000000000000000000000001467545753200264220ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/client.py000066400000000000000000000002301467545753200261460ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.client import OAuth2Client class TikTokOAuth2Client(OAuth2Client): client_id_parameter = "client_key" django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/provider.py000066400000000000000000000026371467545753200265370ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.tiktok.scope import TikTokScope from allauth.socialaccount.providers.tiktok.views import TikTokOAuth2Adapter class TikTokAccount(ProviderAccount): def get_username(self): return self.account.extra_data.get("username") def get_display_name(self): return self.account.extra_data.get("display_name") def get_profile_url(self): return self.account.extra_data.get("profile_deep_link") def get_avatar_url(self): return self.account.extra_data.get("avatar_url") class TikTokProvider(OAuth2Provider): id = "tiktok" name = "TikTok" account_class = TikTokAccount oauth2_adapter_class = TikTokOAuth2Adapter pkce_enabled_default = False def extract_uid(self, data): return str(data["open_id"]) def extract_common_fields(self, data): # TikTok does not provide an email address return { "username": data.get("username") or data.get("display_name"), "name": data.get("display_name"), } def get_default_scope(self): # Requires LoginKit and Scopes with user.info.basic and user.info.profile enabled return [TikTokScope.user_info_basic.value, TikTokScope.user_info_profile.value] provider_classes = [TikTokProvider] django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/scope.py000066400000000000000000000002051467545753200260030ustar00rootroot00000000000000from enum import Enum class TikTokScope(Enum): user_info_basic = "user.info.basic" user_info_profile = "user.info.profile" django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/tests.py000066400000000000000000000014051467545753200260370ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TikTokProvider class TikTokTests(OAuth2TestsMixin, TestCase): provider_id = TikTokProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "data": { "user": { "open_id": "44322889", "username": "username123", "display_name": "Nice Display Name", "avatar_url": "https://example.com/avatar.jpg", "profile_deep_link": "https://example.com/profile" } } } """, ) def get_expected_to_str(self): return "username123" django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/urls.py000066400000000000000000000002461467545753200256640ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import TikTokProvider urlpatterns = default_urlpatterns(TikTokProvider) django-allauth-65.0.2/allauth/socialaccount/providers/tiktok/views.py000066400000000000000000000034511467545753200260350ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from allauth.socialaccount.providers.tiktok.client import TikTokOAuth2Client from allauth.socialaccount.providers.tiktok.scope import TikTokScope class TikTokOAuth2Adapter(OAuth2Adapter): provider_id = "tiktok" access_token_url = "https://open.tiktokapis.com/v2/oauth/token/" authorize_url = "https://www.tiktok.com/v2/auth/authorize/" # https://developers.tiktok.com/doc/tiktok-api-v2-get-user-info/ profile_url = "https://open.tiktokapis.com/v2/user/info/" client_class = TikTokOAuth2Client scope_delimiter = "," def get_query_fields(self): fields = [] if TikTokScope.user_info_basic.value in self.get_provider().get_scope(): fields += ["open_id", "display_name", "avatar_url"] if TikTokScope.user_info_profile.value in self.get_provider().get_scope(): fields += ["username", "profile_deep_link"] return ",".join(fields) def complete_login(self, request, app, token, **kwargs): headers = { "Authorization": f"Bearer {token.token}", "Client-ID": app.client_id, } params = {"fields": self.get_query_fields()} response = ( get_adapter() .get_requests_session() .get(self.profile_url, headers=headers, params=params) ) response.raise_for_status() data = response.json() user_info = data.get("data", {}).get("user") return self.get_provider().sociallogin_from_response(request, user_info) oauth2_login = OAuth2LoginView.adapter_view(TikTokOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(TikTokOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/trainingpeaks/000077500000000000000000000000001467545753200256555ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/trainingpeaks/__init__.py000066400000000000000000000000001467545753200277540ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/trainingpeaks/provider.py000066400000000000000000000027061467545753200300660ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.trainingpeaks.views import ( TrainingPeaksOAuth2Adapter, ) class TrainingPeaksAccount(ProviderAccount): def get_profile_url(self): return "https://app.trainingpeaks.com" def get_avatar_url(self): return None class TrainingPeaksProvider(OAuth2Provider): id = "trainingpeaks" name = "TrainingPeaks" account_class = TrainingPeaksAccount oauth2_adapter_class = TrainingPeaksOAuth2Adapter def extract_uid(self, data): return str(data["Id"]) def extract_common_fields(self, data): extra_common = super(TrainingPeaksProvider, self).extract_common_fields(data) firstname = data.get("FirstName") lastname = data.get("LastName") # fallback username as there is actually no Username in response username = firstname.strip().lower() + "." + lastname.strip().lower() name = " ".join(part for part in (firstname, lastname) if part) extra_common.update( username=data.get("username", username), email=data.get("Email"), first_name=firstname, last_name=lastname, name=name.strip(), ) return extra_common def get_default_scope(self): return ["athlete:profile"] provider_classes = [TrainingPeaksProvider] django-allauth-65.0.2/allauth/socialaccount/providers/trainingpeaks/tests.py000066400000000000000000000053621467545753200273770ustar00rootroot00000000000000""" Run just this suite: python manage.py test allauth.socialaccount.providers.trainingpeaks.tests.TrainingPeaksTests """ from collections import namedtuple from django.test.utils import override_settings from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TrainingPeaksProvider from .views import TrainingPeaksOAuth2Adapter class TrainingPeaksTests(OAuth2TestsMixin, TestCase): provider_id = TrainingPeaksProvider.id def get_mocked_response(self): return MockedResponse( 200, """{ "Id": 123456, "FirstName": "John", "LastName": "Doe", "Email": "user@example.com", "DateOfBirth": "1986-02-01T00:00:00", "CoachedBy": 987654, "Weight": 87.5223617553711 }""", ) # noqa def get_expected_to_str(self): return "user@example.com" def get_login_response_json(self, with_refresh_token=True): rtoken = "" if with_refresh_token: rtoken = ',"refresh_token": "testrf"' return ( """{ "access_token" : "testac", "token_type" : "bearer", "expires_in" : 600, "scope": "scopes granted" %s }""" % rtoken ) def test_default_use_sandbox_uri(self): adapter = TrainingPeaksOAuth2Adapter(None) self.assertTrue(".sandbox." in adapter.authorize_url) self.assertTrue(".sandbox." in adapter.access_token_url) self.assertTrue(".sandbox." in adapter.profile_url) @override_settings( SOCIALACCOUNT_PROVIDERS={"trainingpeaks": {"USE_PRODUCTION": True}} ) def test_use_production_uri(self): adapter = TrainingPeaksOAuth2Adapter(None) self.assertFalse(".sandbox." in adapter.authorize_url) self.assertFalse(".sandbox." in adapter.access_token_url) self.assertFalse(".sandbox." in adapter.profile_url) def test_scope_from_default(self): Request = namedtuple("request", ["GET"]) mock_request = Request(GET={}) scope = self.provider.get_scope_from_request(mock_request) self.assertTrue("athlete:profile" in scope) @override_settings( SOCIALACCOUNT_PROVIDERS={ "trainingpeaks": {"SCOPE": ["athlete:profile", "workouts", "workouts:wod"]} } ) def test_scope_from_settings(self): Request = namedtuple("request", ["GET"]) mock_request = Request(GET={}) scope = self.provider.get_scope_from_request(mock_request) for item in ("athlete:profile", "workouts", "workouts:wod"): self.assertTrue(item in scope) django-allauth-65.0.2/allauth/socialaccount/providers/trainingpeaks/urls.py000066400000000000000000000002641467545753200272160ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import TrainingPeaksProvider urlpatterns = default_urlpatterns(TrainingPeaksProvider) django-allauth-65.0.2/allauth/socialaccount/providers/trainingpeaks/views.py000066400000000000000000000035501467545753200273670ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class TrainingPeaksOAuth2Adapter(OAuth2Adapter): # https://github.com/TrainingPeaks/PartnersAPI/wiki/OAuth provider_id = "trainingpeaks" def get_settings(self): """Provider settings""" return app_settings.PROVIDERS.get(self.provider_id, {}) def get_hostname(self): """Return hostname depending on sandbox setting""" settings = self.get_settings() if settings.get("USE_PRODUCTION"): return "trainingpeaks.com" return "sandbox.trainingpeaks.com" @property def access_token_url(self): return "https://oauth." + self.get_hostname() + "/oauth/token" @property def authorize_url(self): return "https://oauth." + self.get_hostname() + "/OAuth/Authorize" @property def profile_url(self): return "https://api." + self.get_hostname() + "/v1/athlete/profile" @property def api_hostname(self): """Return https://api.hostname.tld""" return "https://api." + self.get_hostname() # https://oauth.sandbox.trainingpeaks.com/oauth/deauthorize scope_delimiter = " " def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} response = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) response.raise_for_status() extra_data = response.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(TrainingPeaksOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(TrainingPeaksOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/trello/000077500000000000000000000000001467545753200243175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/trello/__init__.py000066400000000000000000000000001467545753200264160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/trello/provider.py000066400000000000000000000023011467545753200265170ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.trello.views import TrelloOAuthAdapter class TrelloAccount(ProviderAccount): def get_profile_url(self): return None def get_avatar_url(self): return None class TrelloProvider(OAuthProvider): id = "trello" name = "Trello" account_class = TrelloAccount oauth_adapter_class = TrelloOAuthAdapter def get_default_scope(self): return ["read"] def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict( email=data.get("email"), username=data.get("username"), name=data.get("name"), ) def get_auth_params_from_request(self, request, action): data = super().get_auth_params_from_request(request, action) data["type"] = "web_server" data["name"] = self.app.name # define here for how long it will be, this can be configured on the # social app data["expiration"] = "never" return data provider_classes = [TrelloProvider] django-allauth-65.0.2/allauth/socialaccount/providers/trello/tests.py000066400000000000000000000010551467545753200260340ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TrelloProvider class TrelloTests(OAuthTestsMixin, TestCase): provider_id = TrelloProvider.id def get_mocked_response(self): return [ MockedResponse( 200, r""" {"id": "123", "email": "raymond.penners@example.com", "username": "pennersr", "name": "Raymond"} """, ), ] # noqa def get_expected_to_str(self): return "pennersr" django-allauth-65.0.2/allauth/socialaccount/providers/trello/urls.py000066400000000000000000000002451467545753200256570ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import TrelloProvider urlpatterns = default_urlpatterns(TrelloProvider) django-allauth-65.0.2/allauth/socialaccount/providers/trello/views.py000066400000000000000000000022251467545753200260270ustar00rootroot00000000000000from django.utils.http import urlencode from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class TrelloOAuthAdapter(OAuthAdapter): provider_id = "trello" request_token_url = "https://trello.com/1/OAuthGetRequestToken" authorize_url = "https://trello.com/1/OAuthAuthorizeToken" access_token_url = "https://trello.com/1/OAuthGetAccessToken" def complete_login(self, request, app, token, response): # we need to get the member id and the other information info_url = "{base}?{query}".format( base="https://api.trello.com/1/members/me", query=urlencode({"key": app.key, "token": response.get("oauth_token")}), ) resp = get_adapter().get_requests_session().get(info_url) resp.raise_for_status() extra_data = resp.json() result = self.get_provider().sociallogin_from_response(request, extra_data) return result oauth_login = OAuthLoginView.adapter_view(TrelloOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(TrelloOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/tumblr/000077500000000000000000000000001467545753200243235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/tumblr/__init__.py000066400000000000000000000000261467545753200264320ustar00rootroot00000000000000__author__ = "jshedd" django-allauth-65.0.2/allauth/socialaccount/providers/tumblr/provider.py000066400000000000000000000013371467545753200265330ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.tumblr.views import TumblrOAuthAdapter class TumblrAccount(ProviderAccount): def get_profile_url_(self): return "http://%s.tumblr.com/" % self.account.extra_data.get("name") class TumblrProvider(OAuthProvider): id = "tumblr" name = "Tumblr" account_class = TumblrAccount oauth_adapter_class = TumblrOAuthAdapter def extract_uid(self, data): return data["name"] def extract_common_fields(self, data): return dict( first_name=data.get("name"), ) provider_classes = [TumblrProvider] django-allauth-65.0.2/allauth/socialaccount/providers/tumblr/tests.py000066400000000000000000000017461467545753200260470ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TumblrProvider class TumblrTests(OAuthTestsMixin, TestCase): provider_id = TumblrProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """ { "meta": { "status": 200, "msg": "OK" }, "response": { "user": { "following": 263, "default_post_format": "html", "name": "derekg", "likes": 606, "blogs": [ { "name": "derekg", "title": "Derek Gottfrid", "url": "http://derekg.org/", "tweet": "auto", "primary": true, "followers": 33004929 }, { "name": "ihatehipstrz", "title": "I Hate Hipstrz" } ] } } } """, ) ] def get_expected_to_str(self): return "derekg" django-allauth-65.0.2/allauth/socialaccount/providers/tumblr/urls.py000066400000000000000000000002451467545753200256630ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import TumblrProvider urlpatterns = default_urlpatterns(TumblrProvider) django-allauth-65.0.2/allauth/socialaccount/providers/tumblr/views.py000066400000000000000000000020451467545753200260330ustar00rootroot00000000000000import json from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class TumblrAPI(OAuth): url = "http://api.tumblr.com/v2/user/info" def get_user_info(self): data = json.loads(self.query(self.url)) return data["response"]["user"] class TumblrOAuthAdapter(OAuthAdapter): provider_id = "tumblr" request_token_url = "https://www.tumblr.com/oauth/request_token" access_token_url = "https://www.tumblr.com/oauth/access_token" authorize_url = "https://www.tumblr.com/oauth/authorize" def complete_login(self, request, app, token, response): client = TumblrAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info() return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(TumblrOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(TumblrOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/twentythreeandme/000077500000000000000000000000001467545753200264055ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twentythreeandme/__init__.py000066400000000000000000000000001467545753200305040ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twentythreeandme/provider.py000066400000000000000000000014731467545753200306160ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.twentythreeandme.views import ( TwentyThreeAndMeOAuth2Adapter, ) class TwentyThreeAndMeAccount(ProviderAccount): pass class TwentyThreeAndMeProvider(OAuth2Provider): id = "twentythreeandme" slug = "23andme" name = "23andMe" account_class = TwentyThreeAndMeAccount oauth2_adapter_class = TwentyThreeAndMeOAuth2Adapter def extract_uid(self, data): return data["id"] def get_default_scope(self): scope = ["basic"] return scope def extract_common_fields(self, data): return dict( email=data.get("email"), ) provider_classes = [TwentyThreeAndMeProvider] django-allauth-65.0.2/allauth/socialaccount/providers/twentythreeandme/tests.py000066400000000000000000000015701467545753200301240ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TwentyThreeAndMeProvider class TwentyThreeAndMeTests(OAuth2TestsMixin, TestCase): provider_id = TwentyThreeAndMeProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "profiles": [ {"id": "56c46bdb0902f8e2", "genotyped": false} ], "id": "b4b975a5a6a1b80b" } """, ) def get_expected_to_str(self): return "23andMe" def get_login_response_json(self, with_refresh_token=True): return """ { "access_token":"testac", "token_type":"bearer", "expires_in": 86400, "refresh_token":"33c53cd7bb", "scope":"basic" }""" django-allauth-65.0.2/allauth/socialaccount/providers/twentythreeandme/urls.py000066400000000000000000000002721467545753200277450ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import TwentyThreeAndMeProvider urlpatterns = default_urlpatterns(TwentyThreeAndMeProvider) django-allauth-65.0.2/allauth/socialaccount/providers/twentythreeandme/views.py000066400000000000000000000016711467545753200301210ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class TwentyThreeAndMeOAuth2Adapter(OAuth2Adapter): provider_id = "twentythreeandme" access_token_url = "https://api.23andme.com/token" authorize_url = "https://api.23andme.com/authorize" profile_url = "https://api.23andme.com/1/user/" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(TwentyThreeAndMeOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(TwentyThreeAndMeOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/twitch/000077500000000000000000000000001467545753200243205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twitch/__init__.py000066400000000000000000000000001467545753200264170ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twitch/provider.py000066400000000000000000000024451467545753200265310ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.twitch.views import TwitchOAuth2Adapter class TwitchAccount(ProviderAccount): def get_profile_url(self): return "http://twitch.tv/" + self.account.extra_data.get("login") def get_avatar_url(self): # We're using `logo` as a failback for legacy profiles retrieved # with the old https://api.twitch.tv/kraken/user endpoint. logo = self.account.extra_data.get("logo") return self.account.extra_data.get("profile_image_url", logo) def to_str(self): dflt = super(TwitchAccount, self).to_str() return self.account.extra_data.get("login", dflt) class TwitchProvider(OAuth2Provider): id = "twitch" name = "Twitch" account_class = TwitchAccount oauth2_adapter_class = TwitchOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return { "username": data.get("login"), "name": data.get("display_name"), "email": data.get("email"), } def get_default_scope(self): return ["user:read:email"] provider_classes = [TwitchProvider] django-allauth-65.0.2/allauth/socialaccount/providers/twitch/tests.py000066400000000000000000000063571467545753200260470ustar00rootroot00000000000000from django.test.client import RequestFactory from django.urls import reverse from allauth.socialaccount.models import SocialToken from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .provider import TwitchProvider from .views import TwitchOAuth2Adapter class TwitchTests(OAuth2TestsMixin, TestCase): provider_id = TwitchProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "data": [{ "id": "44322889", "login": "dallas", "display_name": "dallas", "type": "staff", "broadcaster_type": "", "description": "Just a gamer playing games and chatting. :)", "profile_image_url": "https://static-cdn.jtvnw.net/jtv_user_pictures/dallas-profile_image-1a2c906ee2c35f12-300x300.png", "offline_image_url": "https://static-cdn.jtvnw.net/jtv_user_pictures/dallas-channel_offline_image-1a2c906ee2c35f12-1920x1080.png", "view_count": 191836881, "email": "login@provider.com" }] } """, ) # noqa def get_expected_to_str(self): return "dallas" def test_response_over_400_raises_OAuth2Error(self): resp_mock = MockedResponse(400, '{"error": "Invalid token"}') expected_error = "Twitch API Error: Invalid token ()" self.check_for_error(resp_mock, expected_error) def test_empty_or_missing_data_key_raises_OAuth2Error(self): resp_mock = MockedResponse(200, '{"data": []}') expected_error = "Invalid data from Twitch API: {'data': []}" self.check_for_error(resp_mock, expected_error) resp_mock = MockedResponse(200, '{"missing_data": "key"}') expected_error = "Invalid data from Twitch API: {'missing_data': 'key'}" self.check_for_error(resp_mock, expected_error) def test_missing_twitch_id_raises_OAuth2Error(self): resp_mock = MockedResponse(200, '{"data": [{"login": "fake_twitch"}]}') expected_error = "Invalid data from Twitch API: {'login': 'fake_twitch'}" self.check_for_error(resp_mock, expected_error) def check_for_error(self, resp_mock, expected_error): with self.assertRaises(OAuth2Error) as error_ctx: self._run_just_complete_login(resp_mock) self.assertEqual(str(error_ctx.exception).replace("u", ""), expected_error) def _run_just_complete_login(self, resp_mock): """ Helper function for checking that Error cases are handled correctly. Running only `complete_login` means we can check that the specific errors are raised before they are caught and rendered to generic error HTML """ request = RequestFactory().get( reverse(self.provider.id + "_login"), {"process": "login"}, ) adapter = TwitchOAuth2Adapter(request) app = adapter.get_provider().app token = SocialToken(token="this-is-my-fake-token") with mocked_response(resp_mock): adapter = TwitchOAuth2Adapter(request) adapter.complete_login(request, app, token) django-allauth-65.0.2/allauth/socialaccount/providers/twitch/urls.py000066400000000000000000000002461467545753200256610ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import TwitchProvider urlpatterns = default_urlpatterns(TwitchProvider) django-allauth-65.0.2/allauth/socialaccount/providers/twitch/views.py000066400000000000000000000030071467545753200260270ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import OAuth2Error from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class TwitchOAuth2Adapter(OAuth2Adapter): provider_id = "twitch" access_token_url = "https://id.twitch.tv/oauth2/token" authorize_url = "https://id.twitch.tv/oauth2/authorize" profile_url = "https://api.twitch.tv/helix/users" def complete_login(self, request, app, token, **kwargs): headers = { "Authorization": "Bearer {}".format(token.token), "Client-ID": app.client_id, } response = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) data = response.json() if response.status_code >= 400: error = data.get("error", "") message = data.get("message", "") raise OAuth2Error("Twitch API Error: %s (%s)" % (error, message)) try: user_info = data.get("data", [])[0] except IndexError: raise OAuth2Error("Invalid data from Twitch API: %s" % (data)) if "id" not in user_info: raise OAuth2Error("Invalid data from Twitch API: %s" % (user_info)) return self.get_provider().sociallogin_from_response(request, user_info) oauth2_login = OAuth2LoginView.adapter_view(TwitchOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(TwitchOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/twitter/000077500000000000000000000000001467545753200245205ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twitter/__init__.py000066400000000000000000000000001467545753200266170ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twitter/provider.py000066400000000000000000000034311467545753200267250ustar00rootroot00000000000000from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter class TwitterAccount(ProviderAccount): def get_screen_name(self): """The screen name is the username of the Twitter account.""" return self.account.extra_data.get("screen_name") def get_profile_url(self): ret = None screen_name = self.get_screen_name() if screen_name: ret = "http://twitter.com/" + screen_name return ret def get_avatar_url(self): ret = None profile_image_url = self.account.extra_data.get("profile_image_url") if profile_image_url: # Hmm, hack to get our hands on the large image. Not # really documented, but seems to work. ret = profile_image_url.replace("_normal", "") return ret def to_str(self): screen_name = self.get_screen_name() return screen_name or super(TwitterAccount, self).to_str() class TwitterProvider(OAuthProvider): id = "twitter" name = "Twitter" account_class = TwitterAccount oauth_adapter_class = TwitterOAuthAdapter def get_auth_url(self, request, action): if action == AuthAction.REAUTHENTICATE: url = "https://api.twitter.com/oauth/authorize" else: url = "https://api.twitter.com/oauth/authenticate" return url def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( username=data.get("screen_name"), name=data.get("name"), email=data.get("email"), ) provider_classes = [TwitterProvider] django-allauth-65.0.2/allauth/socialaccount/providers/twitter/tests.py000066400000000000000000000077321467545753200262450ustar00rootroot00000000000000from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TwitterProvider class TwitterTests(OAuthTestsMixin, TestCase): provider_id = TwitterProvider.id def get_mocked_response(self): # TODO: Replace with actual/complete Twitter response return [ MockedResponse( 200, r""" {"follow_request_sent": false, "profile_use_background_image": true, "id": 45671919, "verified": false, "profile_text_color": "333333", "profile_image_url_https": "https://pbs.twimg.com/profile_images/793142149/r_normal.png", "profile_sidebar_fill_color": "DDEEF6", "is_translator": false, "geo_enabled": false, "entities": {"description": {"urls": []}}, "followers_count": 43, "protected": false, "location": "The Netherlands", "default_profile_image": false, "id_str": "45671919", "status": {"contributors": null, "truncated": false, "text": "RT @denibertovic: Okay I'm definitely using django-allauth from now on. So easy to set up, far less time consuming, and it just works. #dja\u2026", "in_reply_to_status_id": null, "id": 400658301702381568, "favorite_count": 0, "source": "Twitter Web Client", "retweeted": true, "coordinates": null, "entities": {"symbols": [], "user_mentions": [{"indices": [3, 16], "screen_name": "denibertovic", "id": 23508244, "name": "Deni Bertovic", "id_str": "23508244"}], "hashtags": [{"indices": [135, 139], "text": "dja"}], "urls": []}, "in_reply_to_screen_name": null, "id_str": "400658301702381568", "retweet_count": 6, "in_reply_to_user_id": null, "favorited": false, "retweeted_status": {"lang": "en", "favorited": false, "in_reply_to_user_id": null, "contributors": null, "truncated": false, "text": "Okay I'm definitely using django-allauth from now on. So easy to set up, far less time consuming, and it just works. #django", "created_at": "Sun Jul 28 19:56:26 +0000 2013", "retweeted": true, "in_reply_to_status_id": null, "coordinates": null, "id": 361575897674956800, "entities": {"symbols": [], "user_mentions": [], "hashtags": [{"indices": [117, 124], "text": "django"}], "urls": []}, "in_reply_to_status_id_str": null, "in_reply_to_screen_name": null, "source": "web", "place": null, "retweet_count": 6, "geo": null, "in_reply_to_user_id_str": null, "favorite_count": 8, "id_str": "361575897674956800"}, "geo": null, "in_reply_to_user_id_str": null, "lang": "en", "created_at": "Wed Nov 13 16:15:57 +0000 2013", "in_reply_to_status_id_str": null, "place": null}, "utc_offset": 3600, "statuses_count": 39, "description": "", "friends_count": 83, "profile_link_color": "0084B4", "profile_image_url": "http://pbs.twimg.com/profile_images/793142149/r_normal.png", "notifications": false, "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", "profile_background_color": "C0DEED", "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", "name": "Raymond Penners", "lang": "nl", "profile_background_tile": false, "favourites_count": 0, "screen_name": "pennersr", "url": null, "created_at": "Mon Jun 08 21:10:45 +0000 2009", "contributors_enabled": false, "time_zone": "Amsterdam", "profile_sidebar_border_color": "C0DEED", "default_profile": true, "following": false, "listed_count": 1} """, ) ] # noqa def get_expected_to_str(self): return "pennersr" def test_login(self): super().test_login() account = SocialAccount.objects.get(uid="45671919") tw_account = account.get_provider_account() self.assertEqual(tw_account.get_screen_name(), "pennersr") self.assertEqual( tw_account.get_avatar_url(), "http://pbs.twimg.com/profile_images/793142149/r.png", ) self.assertEqual(tw_account.get_profile_url(), "http://twitter.com/pennersr") self.assertEqual(tw_account.to_str(), "pennersr") django-allauth-65.0.2/allauth/socialaccount/providers/twitter/urls.py000066400000000000000000000002471467545753200260620ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import TwitterProvider urlpatterns = default_urlpatterns(TwitterProvider) django-allauth-65.0.2/allauth/socialaccount/providers/twitter/views.py000066400000000000000000000025651467545753200262370ustar00rootroot00000000000000import json from allauth.socialaccount.app_settings import QUERY_EMAIL from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class TwitterAPI(OAuth): """ Verifying twitter credentials """ _base_url = "https://api.twitter.com/1.1/account/verify_credentials.json" url = _base_url + "?include_email=true" if QUERY_EMAIL else _base_url def get_user_info(self): user = json.loads(self.query(self.url)) return user class TwitterOAuthAdapter(OAuthAdapter): provider_id = "twitter" request_token_url = "https://api.twitter.com/oauth/request_token" access_token_url = "https://api.twitter.com/oauth/access_token" # Issue #42 -- this one authenticates over and over again... # authorize_url = 'https://api.twitter.com/oauth/authorize' authorize_url = "https://api.twitter.com/oauth/authenticate" def complete_login(self, request, app, token, response): client = TwitterAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info() return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(TwitterOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(TwitterOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/twitter_oauth2/000077500000000000000000000000001467545753200260025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twitter_oauth2/__init__.py000066400000000000000000000000001467545753200301010ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/twitter_oauth2/provider.py000066400000000000000000000026761467545753200302210ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.twitter_oauth2.views import ( TwitterOAuth2Adapter, ) class TwitterOAuth2Account(ProviderAccount): def get_username(self): return self.account.extra_data.get("username") def get_profile_url(self): username = self.get_username() if username: return "https://twitter.com/" + username return None def get_avatar_url(self): return self.account.extra_data.get("profile_image_url") class TwitterOAuth2Provider(OAuth2Provider): id = "twitter_oauth2" name = "Twitter" account_class = TwitterOAuth2Account oauth2_adapter_class = TwitterOAuth2Adapter pkce_enabled_default = True def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict( name=data["name"], username=data["username"], ) def get_fields(self): settings = self.get_settings() default_fields = [ "id", "name", "username", "verified", "profile_image_url", "created_at", ] return settings.get("FIELDS", default_fields) def get_default_scope(self): return ["users.read", "tweet.read"] provider_classes = [TwitterOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/twitter_oauth2/tests.py000066400000000000000000000015471467545753200275250ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import TwitterOAuth2Provider class TwitterOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = TwitterOAuth2Provider.id def get_mocked_response(self): return MockedResponse( 200, """{ "data": { "created_at": "2020-09-02T13:39:14.000Z", "id": "1301152652357595137", "verified": false, "username": "realllkk520", "name": "realllkk520", "profile_image_url": "https://pbs.twimg.com/profile_images/1537259565632593920/OoRGPbUg_normal.jpg" } } """, ) # noqa def get_expected_to_str(self): return "realllkk520" django-allauth-65.0.2/allauth/socialaccount/providers/twitter_oauth2/urls.py000066400000000000000000000002641467545753200273430ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import TwitterOAuth2Provider urlpatterns = default_urlpatterns(TwitterOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/twitter_oauth2/views.py000066400000000000000000000025671467545753200275230ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class TwitterOAuth2Adapter(OAuth2Adapter): provider_id = "twitter_oauth2" access_token_url = "https://api.twitter.com/2/oauth2/token" authorize_url = "https://twitter.com/i/oauth2/authorize" profile_url = "https://api.twitter.com/2/users/me" basic_auth = True def complete_login(self, request, app, access_token, **kwargs): extra_data = self.get_user_info(access_token) return self.get_provider().sociallogin_from_response(request, extra_data) def get_user_info(self, token): fields = self.get_provider().get_fields() headers = {} headers.update(self.get_provider().get_settings().get("HEADERS", {})) headers["Authorization"] = " ".join(["Bearer", token.token]) resp = ( get_adapter() .get_requests_session() .get( url=self.profile_url, params={"user.fields": ",".join(fields)}, headers=headers, ) ) resp.raise_for_status() data = resp.json()["data"] return data oauth2_login = OAuth2LoginView.adapter_view(TwitterOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(TwitterOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/untappd/000077500000000000000000000000001467545753200244715ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/untappd/__init__.py000066400000000000000000000000001467545753200265700ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/untappd/client.py000066400000000000000000000036631467545753200263310ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) class UntappdOAuth2Client(OAuth2Client): """ Custom client because Untappd: * uses redirect_url instead of redirect_uri * nests access_token inside an extra 'response' object """ def get_access_token(self, code, pkce_code_verifier=None): from allauth.socialaccount.providers.untappd.provider import ( UntappdProvider, ) data = { "client_id": self.consumer_key, "redirect_url": self.callback_url, "grant_type": "authorization_code", "response_type": "code", "client_secret": self.consumer_secret, "code": code, } params = None self._strip_empty_keys(data) url = self.access_token_url if self.access_token_method == "GET": params = data data = None if data and pkce_code_verifier: data["code_verifier"] = pkce_code_verifier # Allow custom User Agent to comply with Untappd API settings = app_settings.PROVIDERS.get(UntappdProvider.id, {}) headers = {"User-Agent": settings.get("USER_AGENT", "django-allauth")} # TODO: Proper exception handling resp = ( get_adapter() .get_requests_session() .request( self.access_token_method, url, params=params, data=data, headers=headers, ) ) access_token = None if resp.status_code == 200: access_token = resp.json()["response"] if not access_token or "access_token" not in access_token: raise OAuth2Error("Error retrieving access token: %s" % resp.content) return access_token django-allauth-65.0.2/allauth/socialaccount/providers/untappd/provider.py000066400000000000000000000033011467545753200266720ustar00rootroot00000000000000from django.urls import reverse from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.untappd.views import UntappdOAuth2Adapter class UntappdAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("untappd_url") def get_avatar_url(self): return self.account.extra_data.get("user_avatar") def get_user_data(self): return self.account.extra_data.get("response", {}).get("user", {}) class UntappdProvider(OAuth2Provider): id = "untappd" name = "Untappd" account_class = UntappdAccount oauth2_adapter_class = UntappdOAuth2Adapter def get_auth_params_from_request(self, request, action): params = super().get_auth_params_from_request(request, action) # Untappd uses redirect_url instead of redirect_uri params["redirect_url"] = request.build_absolute_uri( reverse(self.id + "_callback") ) return params def extract_uid(self, data): return str(data["response"]["user"]["uid"]) def extract_common_fields(self, data): user = data["response"]["user"] return dict( username=user["user_name"], name=user["first_name"] + " " + user["last_name"], ) def extract_email_addresses(self, data): ret = [ EmailAddress( email=data["response"]["user"]["settings"]["email_address"], verified=True, primary=True, ) ] return ret provider_classes = [UntappdProvider] django-allauth-65.0.2/allauth/socialaccount/providers/untappd/tests.py000066400000000000000000000055731467545753200262170ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import UntappdProvider class UntappdTests(OAuth2TestsMixin, TestCase): provider_id = UntappdProvider.id def get_login_response_json(self, with_refresh_token=True): return """ { "meta": { "http_code": 200 }, "response": { "access_token": "testac" } }""" def get_mocked_response(self): return MockedResponse( 200, """ { "meta":{ "code":200, "response_time":{ "time":0.29, "measure":"seconds" }, "init_time":{ "time":0.011, "measure":"seconds" } }, "notifications":{ "type":"notifications", "unread_count":{ "comments":0, "toasts":0, "friends":0, "messages":0, "news":0 } }, "response":{ "user":{ "uid":123456, "id":123456, "user_name":"groovecoder", "first_name":"", "last_name":"", "user_avatar":"https:\\/\\/gravatar.com\\/avatar\\/ec25d046746de3be33779256f6957d8f?size=100&d=https%3A%2F%2Funtappd.akamaized.net%2Fsite%2Fassets%2Fimages%2Fdefault_avatar_v2.jpg%3Fv%3D1", "user_avatar_hd":"https:\\/\\/gravatar.com\\/avatar\\/ec25d046746de3be33779256f6957d8f?size=125&d=https%3A%2F%2Funtappd.akamaized.net%2Fsite%2Fassets%2Fimages%2Fdefault_avatar_v2.jpg%3Fv%3D1", "user_cover_photo":"https:\\/\\/untappd.akamaized.net\\/site\\/assets\\/v3\\/images\\/cover_default.jpg", "user_cover_photo_offset":0, "is_private":0, "location":"Testville", "url":"", "bio":"", "is_supporter":0, "relationship":"self", "untappd_url":"http:\\/\\/untappd.com\\/user\\/testuser", "account_type":"user", "stats":{ "total_badges":43, "total_friends":43, "total_checkins":73, "total_beers":61, "total_created_beers":1, "total_followings":9, "total_photos":31 }, "recent_brews":{}, "checkins":{}, "media":{}, "contact":{}, "date_joined":"Tue, 11 Dec 2012 14:27:53 +0000", "settings":{ "badge":{ "badges_to_facebook":1, "badges_to_twitter":1 }, "checkin":{ "checkin_to_facebook":0, "checkin_to_twitter":0, "checkin_to_foursquare":0 }, "navigation":{ "default_to_checkin":0 }, "email_address":"test@example.com" } } } } """, ) def get_expected_to_str(self): return "groovecoder" django-allauth-65.0.2/allauth/socialaccount/providers/untappd/urls.py000066400000000000000000000002501467545753200260250ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import UntappdProvider urlpatterns = default_urlpatterns(UntappdProvider) django-allauth-65.0.2/allauth/socialaccount/providers/untappd/views.py000066400000000000000000000021051467545753200261760ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .client import UntappdOAuth2Client class UntappdOAuth2Adapter(OAuth2Adapter): client_class = UntappdOAuth2Client provider_id = "untappd" access_token_url = "https://untappd.com/oauth/authorize/" access_token_method = "GET" authorize_url = "https://untappd.com/oauth/authenticate/" user_info_url = "https://api.untappd.com/v4/user/info/" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get(self.user_info_url, params={"access_token": token.token}) ) extra_data = resp.json() # TODO: get and store the email from the user info json return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(UntappdOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(UntappdOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/vimeo/000077500000000000000000000000001467545753200241355ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vimeo/__init__.py000066400000000000000000000000001467545753200262340ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vimeo/provider.py000066400000000000000000000013041467545753200263370ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.vimeo.views import VimeoOAuthAdapter class VimeoAccount(ProviderAccount): pass class VimeoProvider(OAuthProvider): id = "vimeo" name = "Vimeo" account_class = VimeoAccount oauth_adapter_class = VimeoOAuthAdapter def get_default_scope(self): scope = [] return scope def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict(name=data.get("display_name"), username=data.get("username")) provider_classes = [VimeoProvider] django-allauth-65.0.2/allauth/socialaccount/providers/vimeo/tests.py000066400000000000000000000030431467545753200256510ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import VimeoProvider class VimeoTests(OAuthTestsMixin, TestCase): provider_id = VimeoProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """ {"generated_in":"0.0137", "stat":"ok","person":{ "created_on": "2013-04-08 14:24:47", "id":"17574504", "is_contact":"0", "is_plus":"0","is_pro":"0","is_staff":"0","is_subscribed_to":"0", "username":"user17574504","display_name":"Raymond Penners","location":"", "url":[""],"bio":"","number_of_contacts":"0","number_of_uploads":"0", "number_of_likes":"0","number_of_videos":"0", "number_of_videos_appears_in":"0","number_of_albums":"0", "number_of_channels":"0","number_of_groups":"0", "profileurl":"http:\\/\\/vimeo.com\\/user17574504", "videosurl":"http:\\/\\/vimeo.com\\/user17574504\\/videos", "portraits":{"portrait":[{"height":"30","width":"30", "_content": "http:\\/\\/a.vimeocdn.com\\/images_v6\\/portraits\\/portrait_30_yellow.png"}, {"height":"75","width":"75","_content": "http:\\/\\/a.vimeocdn.com\\/images_v6\\/portraits\\/portrait_75_yellow.png"}, {"height":"100","width":"100","_content": "http:\\/\\/a.vimeocdn.com\\/images_v6\\/portraits\\/portrait_100_yellow.png"}, {"height":"300","width":"300","_content": "http:\\/\\/a.vimeocdn.com\\/images_v6\\/portraits\\/portrait_300_yellow.png"}]}}} """, ) ] def get_expected_to_str(self): return "user17574504" django-allauth-65.0.2/allauth/socialaccount/providers/vimeo/urls.py000066400000000000000000000002431467545753200254730ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import VimeoProvider urlpatterns = default_urlpatterns(VimeoProvider) django-allauth-65.0.2/allauth/socialaccount/providers/vimeo/views.py000066400000000000000000000021121467545753200256400ustar00rootroot00000000000000import json from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class VimeoAPI(OAuth): url = "http://vimeo.com/api/rest/v2?method=vimeo.people.getInfo" def get_user_info(self): url = self.url data = json.loads(self.query(url, params=dict(format="json"))) return data["person"] class VimeoOAuthAdapter(OAuthAdapter): provider_id = "vimeo" request_token_url = "https://vimeo.com/oauth/request_token" access_token_url = "https://vimeo.com/oauth/access_token" authorize_url = "https://vimeo.com/oauth/authorize" def complete_login(self, request, app, token, response): client = VimeoAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info() return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(VimeoOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(VimeoOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/000077500000000000000000000000001467545753200254175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/__init__.py000066400000000000000000000000001467545753200275160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/models.py000066400000000000000000000000001467545753200272420ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/provider.py000066400000000000000000000014331467545753200276240ustar00rootroot00000000000000""" Provider for Patreon """ from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.vimeo_oauth2.views import ( VimeoOAuth2Adapter, ) class VimeoOAuth2Account(ProviderAccount): pass class VimeoOAuth2Provider(OAuth2Provider): id = "vimeo_oauth2" name = "Vimeo" account_class = VimeoOAuth2Account oauth2_adapter_class = VimeoOAuth2Adapter def get_default_scope(self): return ["public", "private"] def extract_uid(self, data): return data.get("uri").split("/")[-1] def extract_common_fields(self, data): return { "fullname": data.get("name"), } provider_classes = [VimeoOAuth2Provider] django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/tests.py000066400000000000000000000020711467545753200271330ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import VimeoOAuth2Provider class VimeoOAuth2Tests(OAuth2TestsMixin, TestCase): provider_id = VimeoOAuth2Provider.id def get_mocked_response(self): return MockedResponse( 200, """{ "uri": "/users/12345", "name": "AllAuth", "link": "https://vimeo.com/user12345", "created_time": "2012-06-04T00:02:16+00:00", "pictures": { "uri": null, "active": false, "type": "default", "sizes": [{ "width": 30, "height": 30, "link": "https://i.vimeocdn.com/portrait/defaults-blue_30x30.png" }], "resource_key": "1234567890abcdef" }, "resource_key": "1234567890abcdef", "account": "pro" }""", ) # noqa def get_expected_to_str(self): return "AllAuth" django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/urls.py000066400000000000000000000003211467545753200267520ustar00rootroot00000000000000"""URLs for Patreon Provider""" from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import VimeoOAuth2Provider urlpatterns = default_urlpatterns(VimeoOAuth2Provider) django-allauth-65.0.2/allauth/socialaccount/providers/vimeo_oauth2/views.py000066400000000000000000000020331467545753200271240ustar00rootroot00000000000000""" Views for PatreonProvider https://www.patreon.com/platform/documentation/oauth """ from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class VimeoOAuth2Adapter(OAuth2Adapter): provider_id = "vimeo_oauth2" access_token_url = "https://api.vimeo.com/oauth/access_token" authorize_url = "https://api.vimeo.com/oauth/authorize" profile_url = "https://api.vimeo.com/me/" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer " + token.token}, ) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(VimeoOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(VimeoOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/vk/000077500000000000000000000000001467545753200234365ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vk/__init__.py000066400000000000000000000000001467545753200255350ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/vk/provider.py000066400000000000000000000025421467545753200256450ustar00rootroot00000000000000from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.vk.views import VKOAuth2Adapter class VKAccount(ProviderAccount): def get_profile_url(self): return "https://vk.com/id%s" % self.account.extra_data.get("id") def get_avatar_url(self): ret = None photo_big_url = self.account.extra_data.get("photo_big") photo_medium_url = self.account.extra_data.get("photo_medium") if photo_big_url: return photo_big_url elif photo_medium_url: return photo_medium_url else: return ret class VKProvider(OAuth2Provider): id = "vk" name = "VK" account_class = VKAccount oauth2_adapter_class = VKOAuth2Adapter def get_default_scope(self): scope = [] if app_settings.QUERY_EMAIL: scope.append("email") return scope def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): return dict( email=data.get("email"), last_name=data.get("last_name"), username=data.get("screen_name"), first_name=data.get("first_name"), ) provider_classes = [VKProvider] django-allauth-65.0.2/allauth/socialaccount/providers/vk/tests.py000066400000000000000000000023761467545753200251620ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import VKProvider class VKTests(OAuth2TestsMixin, TestCase): provider_id = VKProvider.id def get_mocked_response(self, verified_email=True): return MockedResponse( 200, """ {"response": [{"last_name": "Penners", "university_name": "", "photo": "http://vk.com/images/camera_c.gif", "sex": 2, "photo_medium": "http://vk.com/images/camera_b.gif", "relation": "0", "timezone": 1, "photo_big": "http://vk.com/images/camera_a.gif", "id": 219004864, "universities": [], "city": "1430", "first_name": "Raymond", "faculty_name": "", "online": 1, "counters": {"videos": 0, "online_friends": 0, "notes": 0, "audios": 0, "photos": 0, "followers": 0, "groups": 0, "user_videos": 0, "albums": 0, "friends": 0}, "home_phone": "", "faculty": 0, "nickname": "", "screen_name": "id219004864", "has_mobile": 1, "country": "139", "university": 0, "graduation": 0, "activity": "", "last_seen": {"time": 1377805189}}]} """, ) def get_expected_to_str(self): return "Raymond Penners" def get_login_response_json(self, with_refresh_token=True): return '{"user_id": 219004864, "access_token":"testac"}' django-allauth-65.0.2/allauth/socialaccount/providers/vk/urls.py000066400000000000000000000002361467545753200247760ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import VKProvider urlpatterns = default_urlpatterns(VKProvider) django-allauth-65.0.2/allauth/socialaccount/providers/vk/views.py000066400000000000000000000030531467545753200251460ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) USER_FIELDS = [ "first_name", "last_name", "nickname", "screen_name", "sex", "bdate", "city", "country", "timezone", "photo", "photo_medium", "photo_big", "photo_max_orig", "has_mobile", "contacts", "education", "online", "counters", "relation", "last_seen", "activity", "universities", ] class VKOAuth2Adapter(OAuth2Adapter): provider_id = "vk" access_token_url = "https://oauth.vk.com/access_token" authorize_url = "https://oauth.vk.com/authorize" profile_url = "https://api.vk.com/method/users.get" def complete_login(self, request, app, token, **kwargs): uid = kwargs["response"].get("user_id") params = { "v": "5.95", "access_token": token.token, "fields": ",".join(USER_FIELDS), } if uid: params["user_ids"] = uid resp = get_adapter().get_requests_session().get(self.profile_url, params=params) resp.raise_for_status() extra_data = resp.json()["response"][0] email = kwargs["response"].get("email") if email: extra_data["email"] = email return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(VKOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(VKOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/wahoo/000077500000000000000000000000001467545753200241335ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/wahoo/__init__.py000066400000000000000000000000001467545753200262320ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/wahoo/provider.py000066400000000000000000000027321467545753200263430ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.wahoo.views import WahooOAuth2Adapter class WahooAccount(ProviderAccount): def get_profile_url(self): return "https://api.wahooligan.com/v1/user" class WahooProvider(OAuth2Provider): id = "wahoo" name = "Wahoo" account_class = WahooAccount oauth2_adapter_class = WahooOAuth2Adapter def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): extra_common = super(WahooProvider, self).extract_common_fields(data) extra_common.update( # Additional properties we ignore: gender, created_at, updated_at height=data.get("height"), weight=data.get("weight"), first=data.get("first"), last=data.get("last"), birth=data.get("birth"), ) return extra_common def extract_email_addresses(self, data): email = EmailAddress( email=data.get("email"), primary=True, verified=False, ) return [email] def get_default_scope(self): scope = ["user_read"] if app_settings.QUERY_EMAIL: scope.append("email") return scope provider_classes = [WahooProvider] django-allauth-65.0.2/allauth/socialaccount/providers/wahoo/tests.py000066400000000000000000000016241467545753200256520ustar00rootroot00000000000000from allauth.socialaccount.providers.wahoo.provider import WahooProvider from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase class WahooTests(OAuth2TestsMixin, TestCase): provider_id = WahooProvider.id def get_mocked_response(self): # https://cloud-api.wahooligan.com/#users return MockedResponse( 200, """ { "id": 60462, "height": "2.0", "weight": "80.0", "first": "Bob", "last": "Smith", "email": "sample@test-domain.com", "birth": "1980-10-02", "gender": 1, "created_at": "2018-10-23T15:38:23.000Z", "updated_at": "2018-10-24T20:46:40.000Z" } """, ) def get_expected_to_str(self): return "sample@test-domain.com" django-allauth-65.0.2/allauth/socialaccount/providers/wahoo/urls.py000066400000000000000000000002441467545753200254720ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import WahooProvider urlpatterns = default_urlpatterns(WahooProvider) django-allauth-65.0.2/allauth/socialaccount/providers/wahoo/views.py000066400000000000000000000017021467545753200256420ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class WahooOAuth2Adapter(OAuth2Adapter): provider_id = "wahoo" access_token_url = "https://api.wahooligan.com/oauth/token" authorize_url = "https://api.wahooligan.com/oauth/authorize" profile_url = "https://api.wahooligan.com/v1/user" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(WahooOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(WahooOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/weibo/000077500000000000000000000000001467545753200241235ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/weibo/__init__.py000066400000000000000000000000001467545753200262220ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/weibo/provider.py000066400000000000000000000017521467545753200263340ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ( ProviderAccount, ProviderException, ) from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.weibo.views import WeiboOAuth2Adapter class WeiboAccount(ProviderAccount): def get_profile_url(self): # profile_url = "u/3195025850" return "http://www.weibo.com/" + self.account.extra_data.get("profile_url") def get_avatar_url(self): return self.account.extra_data.get("avatar_large") class WeiboProvider(OAuth2Provider): id = "weibo" name = "Weibo" account_class = WeiboAccount oauth2_adapter_class = WeiboOAuth2Adapter def extract_uid(self, data): ret = data.get("idstr") if not ret: raise ProviderException("Missing 'idstr'") return ret def extract_common_fields(self, data): return dict(username=data.get("screen_name"), name=data.get("name")) provider_classes = [WeiboProvider] django-allauth-65.0.2/allauth/socialaccount/providers/weibo/tests.py000066400000000000000000000023511467545753200256400ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import WeiboProvider class WeiboTests(OAuth2TestsMixin, TestCase): provider_id = WeiboProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"bi_followers_count": 0, "domain": "", "avatar_large": "http://tp3.sinaimg.cn/3195025850/180/0/0", "block_word": 0, "star": 0, "id": 3195025850, "city": "1", "verified": false, "follow_me": false, "verified_reason": "", "followers_count": 6, "location": "\u5317\u4eac \u4e1c\u57ce\u533a", "mbtype": 0, "profile_url": "u/3195025850", "province": "11", "statuses_count": 0, "description": "", "friends_count": 0, "online_status": 0, "mbrank": 0, "idstr": "3195025850", "profile_image_url": "http://tp3.sinaimg.cn/3195025850/50/0/0", "allow_all_act_msg": false, "allow_all_comment": true, "geo_enabled": true, "name": "pennersr", "lang": "zh-cn", "weihao": "", "remark": "", "favourites_count": 0, "screen_name": "pennersr", "url": "", "gender": "f", "created_at": "Tue Feb 19 19:43:39 +0800 2013", "verified_type": -1, "following": false} """, ) def get_expected_to_str(self): return "pennersr" django-allauth-65.0.2/allauth/socialaccount/providers/weibo/urls.py000066400000000000000000000002441467545753200254620ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import WeiboProvider urlpatterns = default_urlpatterns(WeiboProvider) django-allauth-65.0.2/allauth/socialaccount/providers/weibo/views.py000066400000000000000000000017171467545753200256400ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class WeiboOAuth2Adapter(OAuth2Adapter): provider_id = "weibo" access_token_url = "https://api.weibo.com/oauth2/access_token" authorize_url = "https://api.weibo.com/oauth2/authorize" profile_url = "https://api.weibo.com/2/users/show.json" def complete_login(self, request, app, token, **kwargs): uid = kwargs.get("response", {}).get("uid") resp = ( get_adapter() .get_requests_session() .get(self.profile_url, params={"access_token": token.token, "uid": uid}) ) extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(WeiboOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(WeiboOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/weixin/000077500000000000000000000000001467545753200243215ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/weixin/__init__.py000066400000000000000000000000001467545753200264200ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/weixin/client.py000066400000000000000000000035511467545753200261550ustar00rootroot00000000000000from collections import OrderedDict from django.utils.http import urlencode from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.client import ( OAuth2Client, OAuth2Error, ) class WeixinOAuth2Client(OAuth2Client): def get_redirect_url(self, authorization_url, scope, extra_params): scope = self.scope_delimiter.join(set(scope)) params = { "appid": self.consumer_key, "redirect_uri": self.callback_url, "scope": scope, "response_type": "code", } if self.state: params["state"] = self.state params.update(extra_params) sorted_params = OrderedDict() for param in sorted(params): sorted_params[param] = params[param] return "%s?%s" % (authorization_url, urlencode(sorted_params)) def get_access_token(self, code, pkce_code_verifier=None): data = { "appid": self.consumer_key, "grant_type": "authorization_code", "secret": self.consumer_secret, "code": code, } params = None self._strip_empty_keys(data) url = self.access_token_url if self.access_token_method == "GET": params = data data = None if data and pkce_code_verifier: data["code_verifier"] = pkce_code_verifier # TODO: Proper exception handling resp = ( get_adapter() .get_requests_session() .request(self.access_token_method, url, params=params, data=data) ) access_token = None if resp.status_code == 200: access_token = resp.json() if not access_token or "access_token" not in access_token: raise OAuth2Error("Error retrieving access token: %s" % resp.content) return access_token django-allauth-65.0.2/allauth/socialaccount/providers/weixin/provider.py000066400000000000000000000016421467545753200265300ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.weixin.views import WeixinOAuth2Adapter class WeixinAccount(ProviderAccount): def get_avatar_url(self): return self.account.extra_data.get("headimgurl") def to_str(self): return self.account.extra_data.get( "nickname", super(WeixinAccount, self).to_str() ) class WeixinProvider(OAuth2Provider): id = "weixin" name = "Weixin" account_class = WeixinAccount oauth2_adapter_class = WeixinOAuth2Adapter def extract_uid(self, data): return data["openid"] def get_default_scope(self): return ["snsapi_login"] def extract_common_fields(self, data): return dict(username=data.get("nickname"), name=data.get("nickname")) provider_classes = [WeixinProvider] django-allauth-65.0.2/allauth/socialaccount/providers/weixin/tests.py000066400000000000000000000025721467545753200260430ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import WeixinProvider class WeixinTests(OAuth2TestsMixin, TestCase): provider_id = WeixinProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"access_token": "OezXcEiiBSKSxW0eoylIeO5cPxb4Ks1RpbXGMv9uiV35032zNHGzXcld-EKsSScE3gRZMrUU78skCbp1ShtZnR0dQB8Wr_LUf7FA-H97Lnd2HgQah_GnkQex-vPFsGEwPPcNAV6q1Vz3uRNgL0MUFg", "city": "Pudong New District", "country": "CN", "expires_in": 7200, "headimgurl": "http://wx.qlogo.cn/mmopen/VkvLVEpoJiaibYsVyW8GzxHibzlnqSM7iaX09r6TWUJXCNQHibHz37krvN65HR1ibEpgH5K5sukcIzA3r1C4KQ9qyyX9XIUdY9lNOk/0", "language": "zh_CN", "nickname": "某某某", "openid": "ohS-VwAJ9GEXlplngwybJ3Z-ZHrI", "privilege": [], "province": "Shanghai", "refresh_token": "OezXcEiiBSKSxW0eoylIeO5cPxb4Ks1RpbXGMv9uiV35032zNHGzXcld-EKsSScEbMnnMqVExcSpj7KRAuBA8BU2j2e_FK5dgBe-ro32k7OuHtznwqqBn5QR7LZGo2-P8G7gG0eitjyZ751sFlnTAw", "scope": "snsapi_login", "sex": 1, "unionid": "ohHrhwKnD9TOunEW0eKTS45vS5Qo"}""", ) # noqa def get_expected_to_str(self): # For some reason, WeixinOAuth2Adapter.complete_login runs this line: # extra_data["nickname"] = nickname.encode("raw_unicode_escape").decode( # "utf-8" # ) return "\\u67d0\\u67d0\\u67d0" django-allauth-65.0.2/allauth/socialaccount/providers/weixin/urls.py000066400000000000000000000002461467545753200256620ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import WeixinProvider urlpatterns = default_urlpatterns(WeixinProvider) django-allauth-65.0.2/allauth/socialaccount/providers/weixin/views.py000066400000000000000000000027511467545753200260350ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) from .client import WeixinOAuth2Client class WeixinOAuth2Adapter(OAuth2Adapter): provider_id = "weixin" access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token" profile_url = "https://api.weixin.qq.com/sns/userinfo" client_class = WeixinOAuth2Client @property def authorize_url(self): settings = self.get_provider().get_settings() url = settings.get( "AUTHORIZE_URL", "https://open.weixin.qq.com/connect/qrconnect" ) return url def complete_login(self, request, app, token, **kwargs): openid = kwargs.get("response", {}).get("openid") resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"access_token": token.token, "openid": openid}, ) ) resp.raise_for_status() extra_data = resp.json() nickname = extra_data.get("nickname") if nickname: extra_data["nickname"] = nickname.encode("raw_unicode_escape").decode( "utf-8" ) return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(WeixinOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(WeixinOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/windowslive/000077500000000000000000000000001467545753200253705ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/windowslive/__init__.py000066400000000000000000000000001467545753200274670ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/windowslive/provider.py000066400000000000000000000023441467545753200275770ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.windowslive.views import ( WindowsLiveOAuth2Adapter, ) class WindowsLiveAccount(ProviderAccount): def to_str(self): email = self.account.extra_data.get("emails", {}).get("preferred") if email: return email return super().to_str() class WindowsLiveProvider(OAuth2Provider): id = "windowslive" name = "Live" account_class = WindowsLiveAccount oauth2_adapter_class = WindowsLiveOAuth2Adapter def get_default_scope(self): """ Doc on scopes available at http://msdn.microsoft.com/en-us/library/dn631845.aspx """ return ["wl.basic", "wl.emails"] def extract_uid(self, data): return str(data["id"]) def extract_common_fields(self, data): try: email = data.get("emails").get("preferred") except AttributeError: email = None return dict( email=email, last_name=data.get("last_name"), first_name=data.get("first_name"), ) provider_classes = [WindowsLiveProvider] django-allauth-65.0.2/allauth/socialaccount/providers/windowslive/tests.py000066400000000000000000000016641467545753200271130ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import WindowsLiveProvider class WindowsLiveTests(OAuth2TestsMixin, TestCase): provider_id = WindowsLiveProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "first_name": "James", "last_name": "Smith", "name": "James Smith", "locale": "en_US", "gender": null, "emails": { "personal": null, "account": "jsmith@example.com", "business": null, "preferred": "jsmith@example.com" }, "link": "https://profile.live.com/", "updated_time": "2014-02-07T00:35:27+0000", "id": "83605e110af6ff98" } """, ) def get_expected_to_str(self): return "jsmith@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/windowslive/urls.py000066400000000000000000000002601467545753200267250ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import WindowsLiveProvider urlpatterns = default_urlpatterns(WindowsLiveProvider) django-allauth-65.0.2/allauth/socialaccount/providers/windowslive/views.py000066400000000000000000000026471467545753200271100ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class WindowsLiveOAuth2Adapter(OAuth2Adapter): provider_id = "windowslive" access_token_url = "https://login.live.com/oauth20_token.srf" authorize_url = "https://login.live.com/oauth20_authorize.srf" profile_url = "https://apis.live.net/v5.0/me" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) # example of what's returned (in python format): # {'first_name': 'James', 'last_name': 'Smith', # 'name': 'James Smith', 'locale': 'en_US', 'gender': None, # 'emails': {'personal': None, 'account': 'jsmith@example.com', # 'business': None, 'preferred': 'jsmith@example.com'}, # 'link': 'https://profile.live.com/', # 'updated_time': '2014-02-07T00:35:27+0000', # 'id': '83605e110af6ff98'} resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(WindowsLiveOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(WindowsLiveOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/xing/000077500000000000000000000000001467545753200237635ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/xing/__init__.py000066400000000000000000000000001467545753200260620ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/xing/provider.py000066400000000000000000000020431467545753200261660ustar00rootroot00000000000000from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth.provider import OAuthProvider from allauth.socialaccount.providers.xing.views import XingOAuthAdapter class XingAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("permalink") def get_avatar_url(self): return self.account.extra_data.get("photo_urls", {}).get("large") def to_str(self): dflt = super().to_str() return self.account.extra_data.get("active_email") or dflt class XingProvider(OAuthProvider): id = "xing" name = "Xing" account_class = XingAccount oauth_adapter_class = XingOAuthAdapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict( email=data.get("active_email"), username=data.get("page_name"), first_name=data.get("first_name"), last_name=data.get("last_name"), ) provider_classes = [XingProvider] django-allauth-65.0.2/allauth/socialaccount/providers/xing/tests.py000066400000000000000000000037531467545753200255070ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuthTestsMixin from allauth.tests import MockedResponse, TestCase from .provider import XingProvider class XingTests(OAuthTestsMixin, TestCase): provider_id = XingProvider.id def get_mocked_response(self): return [ MockedResponse( 200, """ {"users":[{"id":"20493333_1cd028","active_email":"raymond.penners@example.com", "badges":[],"birth_date":{"year":null,"month":null,"day":null}, "business_address":{"street":null,"zip_code":null,"city":null,"province":null, "country":"NL","email":null,"fax":null,"phone":null,"mobile_phone":null}, "display_name":"Raymond Penners","educational_background": {"primary_school_id":null,"schools":[],"qualifications":[]}, "employment_status":"EMPLOYEE","first_name":"Raymond","gender":"m", "haves":null,"instant_messaging_accounts":{},"interests":null,"languages": {"nl":null},"last_name":"Penners","organisation_member":null, "page_name":"Raymond_Penners", "permalink":"https://www.xing.com/profile/Raymond_Penners", "photo_urls":{"thumb":"https://www.xing.com/img/n/nobody_m.30x40.jpg", "large":"https://www.xing.com/img/n/nobody_m.140x185.jpg","mini_thumb": "https://www.xing.com/img/n/nobody_m.18x24.jpg","maxi_thumb": "https://www.xing.com/img/n/nobody_m.70x93.jpg","medium_thumb": "https://www.xing.com/img/n/nobody_m.57x75.jpg"},"premium_services":[], "private_address":{"street":null,"zip_code":null,"city":null,"province":null, "country":null,"email":"raymond.penners@example.com","fax":null, "phone":null,"mobile_phone":null},"professional_experience": {"primary_company":{"name":null,"url":null,"tag":null,"title":null, "begin_date":null,"end_date":null,"description":null,"industry":"OTHERS", "company_size":null,"career_level":null},"non_primary_companies":[], "awards":[]},"time_zone":{"utc_offset":2.0,"name":"Europe/Berlin"}, "wants":null,"web_profiles":{}}]} """, ) ] def get_expected_to_str(self): return "raymond.penners@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/xing/urls.py000066400000000000000000000002411467545753200253170ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth.urls import default_urlpatterns from .provider import XingProvider urlpatterns = default_urlpatterns(XingProvider) django-allauth-65.0.2/allauth/socialaccount/providers/xing/views.py000066400000000000000000000020051467545753200254670ustar00rootroot00000000000000import json from allauth.socialaccount.providers.oauth.client import OAuth from allauth.socialaccount.providers.oauth.views import ( OAuthAdapter, OAuthCallbackView, OAuthLoginView, ) class XingAPI(OAuth): url = "https://api.xing.com/v1/users/me.json" def get_user_info(self): user = json.loads(self.query(self.url)) return user class XingOAuthAdapter(OAuthAdapter): provider_id = "xing" request_token_url = "https://api.xing.com/v1/request_token" access_token_url = "https://api.xing.com/v1/access_token" authorize_url = "https://www.xing.com/v1/authorize" def complete_login(self, request, app, token, response): client = XingAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info()["users"][0] return self.get_provider().sociallogin_from_response(request, extra_data) oauth_login = OAuthLoginView.adapter_view(XingOAuthAdapter) oauth_callback = OAuthCallbackView.adapter_view(XingOAuthAdapter) django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/000077500000000000000000000000001467545753200241355ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/__init__.py000066400000000000000000000000001467545753200262340ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/models.py000066400000000000000000000000331467545753200257660ustar00rootroot00000000000000# Create your models here. django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/provider.py000066400000000000000000000022571467545753200263470ustar00rootroot00000000000000from allauth.socialaccount.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.yahoo.views import YahooOAuth2Adapter class YahooAccount(ProviderAccount): pass class YahooProvider(OAuth2Provider): id = "yahoo" name = "Yahoo" account_class = YahooAccount oauth2_adapter_class = YahooOAuth2Adapter def get_default_scope(self): """ Doc on scopes available at https://developer.yahoo.com/oauth2/guide/yahoo_scopes/ """ return ["profile", "email"] def extract_uid(self, data): return data["sub"] def extract_common_fields(self, data): return dict( email=data["email"], last_name=data["family_name"], first_name=data["given_name"], ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("email_verified"): ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [YahooProvider] django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/tests.py000066400000000000000000000013701467545753200256520ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import YahooProvider class YahooTests(OAuth2TestsMixin, TestCase): provider_id = YahooProvider.id def get_mocked_response(self): response_data = """ { "sub": "FSVIDUW3D7FSVIDUW3D72F2F", "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "preferred_username": "j.doe", "email": "janedoe@example.com", "email_verified": true, "picture": "http://example.com/janedoe/me.jpg" } """ # noqa return MockedResponse(200, response_data) def get_expected_to_str(self): return "janedoe@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/urls.py000066400000000000000000000002441467545753200254740ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import YahooProvider urlpatterns = default_urlpatterns(YahooProvider) django-allauth-65.0.2/allauth/socialaccount/providers/yahoo/views.py000066400000000000000000000017321467545753200256470ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class YahooOAuth2Adapter(OAuth2Adapter): provider_id = "yahoo" access_token_url = "https://api.login.yahoo.com/oauth2/get_token" authorize_url = "https://api.login.yahoo.com/oauth2/request_auth" profile_url = "https://api.login.yahoo.com/openid/v1/userinfo" def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} resp = ( get_adapter().get_requests_session().get(self.profile_url, headers=headers) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(YahooOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(YahooOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/yandex/000077500000000000000000000000001467545753200243065ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/yandex/__init__.py000066400000000000000000000000001467545753200264050ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/yandex/provider.py000066400000000000000000000031571467545753200265200ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.yandex.views import YandexOAuth2Adapter class YandexAccount(ProviderAccount): def to_str(self): email = self.account.extra_data.get("default_email") if email: return email return super().to_str() class YandexProvider(OAuth2Provider): id = "yandex" name = "Yandex" account_class = YandexAccount oauth2_adapter_class = YandexOAuth2Adapter def get_default_scope(self): scope = ["login:info"] if app_settings.QUERY_EMAIL: scope.append("login:email") return scope def extract_uid(self, data): return str(data["id"]) def get_user_email(self, data): email = data.get("default_email") if not email: emails = data.get("emails") email = emails[0] if emails else "" return email def extract_common_fields(self, data): email = self.get_user_email(data) return dict( email=email, last_name=data.get("last_name"), username=data.get("display_name"), first_name=data.get("first_name"), ) def extract_email_addresses(self, data): ret = [] email = self.get_user_email(data) if email: ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [YandexProvider] django-allauth-65.0.2/allauth/socialaccount/providers/yandex/tests.py000066400000000000000000000027031467545753200260240ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import YandexProvider class YandexTests(OAuth2TestsMixin, TestCase): provider_id = YandexProvider.id yandex_data = """ { "login": "vasya", "old_social_login": "uid-mmzxrnry", "default_email": "test@yandex.ru", "id": "1000034426", "client_id": "4760187d81bc4b7799476b42b5103713", "emails": [ "test@yandex.ru", "other-test@yandex.ru" ], "openid_identities": [ "http://openid.yandex.ru/vasya/", "http://vasya.ya.ru/" ] }""" def get_mocked_response(self, data=None): if data is None: data = self.yandex_data return MockedResponse(200, data) def get_expected_to_str(self): return "test@yandex.ru" def get_login_response_json(self, with_refresh_token=True): return """ { "access_token":"testac", "refresh_token":"1:GN686QVt0mmakDd9:A4pYuW9LGk0_UnlrMIWklk", "token_type":"bearer", "expires_in":124234123534 }""" django-allauth-65.0.2/allauth/socialaccount/providers/yandex/urls.py000066400000000000000000000002461467545753200256470ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import YandexProvider urlpatterns = default_urlpatterns(YandexProvider) django-allauth-65.0.2/allauth/socialaccount/providers/yandex/views.py000066400000000000000000000017771467545753200260310ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class YandexOAuth2Adapter(OAuth2Adapter): provider_id = "yandex" access_token_url = "https://oauth.yandex.ru/token" authorize_url = "https://oauth.yandex.com/authorize" profile_url = "https://login.yandex.ru/info" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, params={"format": "json"}, headers={"Authorization": f"OAuth {token.token}"}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(YandexOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(YandexOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/ynab/000077500000000000000000000000001467545753200237475ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/ynab/__init__.py000066400000000000000000000000001467545753200260460ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/ynab/provider.py000066400000000000000000000016221467545753200261540ustar00rootroot00000000000000from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.ynab.views import YNABOAuth2Adapter class Scope: ACCESS = "read-only" class YNABAccount(ProviderAccount): pass class YNABProvider(OAuth2Provider): id = "ynab" name = "YNAB" account_class = YNABAccount oauth2_adapter_class = YNABOAuth2Adapter def get_default_scope(self): scope = [Scope.ACCESS] return scope def get_auth_params_from_request(self, request, action): ret = super().get_auth_params_from_request(request, action) if action == AuthAction.REAUTHENTICATE: ret["prompt"] = "select_account consent" return ret def extract_uid(self, data): return str(data["data"]["user"]["id"]) provider_classes = [YNABProvider] django-allauth-65.0.2/allauth/socialaccount/providers/ynab/tests.py000066400000000000000000000041451467545753200254670ustar00rootroot00000000000000from requests.exceptions import HTTPError from django.test.client import RequestFactory from django.test.utils import override_settings from django.urls import reverse from allauth.socialaccount.models import SocialToken from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase, mocked_response from .provider import YNABProvider @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=True, ACCOUNT_SIGNUP_FORM_CLASS=None, ) # ACCOUNT_EMAIL_VERIFICATION=account_settings # .EmailVerificationMethod.MANDATORY) class YNABTests(OAuth2TestsMixin, TestCase): provider_id = YNABProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"data": { "user":{ "id": "abcd1234xyz5678" } } } """, ) def get_expected_to_str(self): return "YNAB" def test_ynab_compelete_login_401(self): from allauth.socialaccount.providers.ynab.views import ( YNABOAuth2Adapter, ) class LessMockedResponse(MockedResponse): def raise_for_status(self): if self.status_code != 200: raise HTTPError(None) request = RequestFactory().get( reverse(self.provider.id + "_login"), dict(process="login") ) adapter = YNABOAuth2Adapter(request) app = adapter.get_provider().app token = SocialToken(token="some_token") response_with_401 = LessMockedResponse( 401, """ {"error": { "errors": [{ "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } }""", ) with mocked_response(response_with_401): with self.assertRaises(HTTPError): adapter.complete_login(request, app, token) django-allauth-65.0.2/allauth/socialaccount/providers/ynab/urls.py000066400000000000000000000002421467545753200253040ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import YNABProvider urlpatterns = default_urlpatterns(YNABProvider) django-allauth-65.0.2/allauth/socialaccount/providers/ynab/views.py000066400000000000000000000020161467545753200254550ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class YNABOAuth2Adapter(OAuth2Adapter): provider_id = "ynab" access_token_url = "https://app.youneedabudget.com/oauth/token" authorize_url = "https://app.youneedabudget.com/oauth/authorize" profile_url = "https://api.youneedabudget.com/v1/user" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer {}".format(token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() login = self.get_provider().sociallogin_from_response(request, extra_data) return login oauth2_login = OAuth2LoginView.adapter_view(YNABOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(YNABOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/zoho/000077500000000000000000000000001467545753200237755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/zoho/__init__.py000066400000000000000000000000001467545753200260740ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/zoho/provider.py000066400000000000000000000022521467545753200262020ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.zoho.views import ZohoOAuth2Adapter class ZohoAccount(ProviderAccount): pass class ZohoProvider(OAuth2Provider): id = "zoho" name = "Zoho" account_class = ZohoAccount oauth2_adapter_class = ZohoOAuth2Adapter def get_default_scope(self): return ["aaaserver.profile.READ"] def extract_uid(self, data): return str(data["ZUID"]) def extract_common_fields(self, data): return dict( email=data["Email"], username=data["Display_Name"], first_name=data["First_Name"], last_name=data["Last_Name"], ) def extract_email_addresses(self, data): ret = [] email = data.get("Email") if email: ret.append( EmailAddress( email=email, verified=False, primary=True, ) ) return ret provider_classes = [ZohoProvider] django-allauth-65.0.2/allauth/socialaccount/providers/zoho/tests.py000066400000000000000000000010041467545753200255040ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import ZohoProvider class ZohoTests(OAuth2TestsMixin, TestCase): provider_id = ZohoProvider.id def get_mocked_response(self): return MockedResponse( 200, """ {"First_Name":"John","Email":"jdoe@example.com", "Last_Name":"Doe","Display_Name":"JDoee","ZUID":1234567} """, ) def get_expected_to_str(self): return "jdoe@example.com" django-allauth-65.0.2/allauth/socialaccount/providers/zoho/urls.py000066400000000000000000000002421467545753200253320ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import ZohoProvider urlpatterns = default_urlpatterns(ZohoProvider) django-allauth-65.0.2/allauth/socialaccount/providers/zoho/views.py000066400000000000000000000017621467545753200255120ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class ZohoOAuth2Adapter(OAuth2Adapter): provider_id = "zoho" access_token_url = "https://accounts.zoho.com/oauth/v2/token" authorize_url = "https://accounts.zoho.com/oauth/v2/auth" profile_url = "https://accounts.zoho.com/oauth/user/info" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer {}".format(token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(ZohoOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(ZohoOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/providers/zoom/000077500000000000000000000000001467545753200240025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/zoom/__init__.py000066400000000000000000000000001467545753200261010ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/providers/zoom/provider.py000066400000000000000000000021731467545753200262110ustar00rootroot00000000000000from allauth.account.models import EmailAddress from allauth.socialaccount.providers.base import ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider from allauth.socialaccount.providers.zoom.views import ZoomOAuth2Adapter class ZoomAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("vanity_url") def get_avatar_url(self): return self.account.extra_data.get("pic_url") class ZoomProvider(OAuth2Provider): id = "zoom" name = "Zoom" account_class = ZoomAccount oauth2_adapter_class = ZoomOAuth2Adapter def extract_uid(self, data): return data["id"] def extract_common_fields(self, data): return dict( email=data["email"], first_name=data["first_name"], last_name=data["last_name"], ) def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("verified"): ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [ZoomProvider] django-allauth-65.0.2/allauth/socialaccount/providers/zoom/tests.py000066400000000000000000000024221467545753200255160ustar00rootroot00000000000000from allauth.socialaccount.tests import OAuth2TestsMixin from allauth.tests import MockedResponse, TestCase from .provider import ZoomProvider class ZoomTests(OAuth2TestsMixin, TestCase): provider_id = ZoomProvider.id def get_mocked_response(self): return MockedResponse( 200, """ { "id": "KdYKjnimT4KPd8FFgQt9FQ", "first_name": "Jane", "last_name": "Dev", "email": "jane.dev@email.com", "type": 2, "role_name": "Owner", "pmi": 1234567890, "use_pmi": false, "vanity_url": "https://janedevinc.zoom.us/my/janedev", "personal_meeting_url": "https://janedevinc.zoom.us/j/1234567890", "timezone": "America/Denver", "verified": 1, "dept": "", "created_at": "2019-04-05T15:24:32Z", "last_login_time": "2019-12-16T18:02:48Z", "last_client_version": "4.6.12611.1124(mac)", "pic_url": "https://janedev.zoom.us/p/KdYKjnimFR5Td8KKdQt9FQ/19f6430f-...", "host_key": "533895", "jid": "kdykjnimt4kpd8kkdqt9fq@xmpp.zoom.us", "group_ids": [], "im_group_ids": [ "3NXCD9VFTCOUH8LD-QciGw" ], "account_id": "gVcjZnYYRLDbb_MfgHuaxg", "language": "en-US", "phone_country": "US", "phone_number": "+1 1234567891", "status": "active" } """, ) def get_expected_to_str(self): return "jane.dev@email.com" django-allauth-65.0.2/allauth/socialaccount/providers/zoom/urls.py000066400000000000000000000002421467545753200253370ustar00rootroot00000000000000from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns from .provider import ZoomProvider urlpatterns = default_urlpatterns(ZoomProvider) django-allauth-65.0.2/allauth/socialaccount/providers/zoom/views.py000066400000000000000000000017231467545753200255140ustar00rootroot00000000000000from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.providers.oauth2.views import ( OAuth2Adapter, OAuth2CallbackView, OAuth2LoginView, ) class ZoomOAuth2Adapter(OAuth2Adapter): provider_id = "zoom" access_token_url = "https://zoom.us/oauth/token" authorize_url = "https://zoom.us/oauth/authorize" profile_url = "https://api.zoom.us/v2/users/me" def complete_login(self, request, app, token, **kwargs): resp = ( get_adapter() .get_requests_session() .get( self.profile_url, headers={"Authorization": "Bearer {}".format(token.token)}, ) ) resp.raise_for_status() extra_data = resp.json() return self.get_provider().sociallogin_from_response(request, extra_data) oauth2_login = OAuth2LoginView.adapter_view(ZoomOAuth2Adapter) oauth2_callback = OAuth2CallbackView.adapter_view(ZoomOAuth2Adapter) django-allauth-65.0.2/allauth/socialaccount/sessions.py000066400000000000000000000035631467545753200232300ustar00rootroot00000000000000from importlib import import_module from urllib.parse import urlparse from django.conf import settings from django.utils.cache import patch_vary_headers engine = import_module(settings.SESSION_ENGINE) SessionStore = engine.SessionStore class LoginSession: """Some providers sometimes POST their responses, which due to CORS/Samesite-cookie rules means that this request cannot access the session as its session cookie is unavailable. We work around this by storing the response in a separate, temporary session and redirecting to a different endpoint that can pick up the flow. """ def __init__(self, request, attribute_name, cookie_name): """ Prepares an provider specific session. """ self.request = request self.attribute_name = attribute_name self.cookie_name = cookie_name self.store = getattr(request, attribute_name, None) if self.store is None: session_key = request.COOKIES.get(cookie_name) self.store = SessionStore(session_key) setattr(request, attribute_name, self.store) def save(self, response): """ Save the session and set a cookie. """ patch_vary_headers(response, ("Cookie",)) self.store.save() kwargs = {} samesite = getattr(settings, "SESSION_COOKIE_SAMESITE", None) if samesite: kwargs["samesite"] = samesite response.set_cookie( self.cookie_name, self.store.session_key, max_age=None, expires=None, domain=settings.SESSION_COOKIE_DOMAIN, # The cookie is only needed on this endpoint path=urlparse(response.url).path, secure=settings.SESSION_COOKIE_SECURE, httponly=None, **kwargs ) def delete(self): self.store.delete() django-allauth-65.0.2/allauth/socialaccount/signals.py000066400000000000000000000016251467545753200230170ustar00rootroot00000000000000from django.dispatch import Signal # Sent after a user successfully authenticates via a social provider, # but before the login is actually processed. This signal is emitted # for social logins, signups and when connecting additional social # accounts to an account. # Provides the arguments "request", "sociallogin" pre_social_login = Signal() # Sent after a user connects a social account to a their local account. # Provides the arguments "request", "sociallogin" social_account_added = Signal() # Sent after a user connects an already existing social account to a # their local account. The social account will have an updated token and # refreshed extra_data. # Provides the arguments "request", "sociallogin" social_account_updated = Signal() # Sent after a user disconnects a social account from their local # account. # Provides the arguments "request", "socialaccount" social_account_removed = Signal() django-allauth-65.0.2/allauth/socialaccount/templatetags/000077500000000000000000000000001467545753200234735ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/templatetags/__init__.py000066400000000000000000000000001467545753200255720ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/templatetags/socialaccount.py000066400000000000000000000053771467545753200267100ustar00rootroot00000000000000from django import template from django.contrib.auth import REDIRECT_FIELD_NAME from django.utils.safestring import mark_safe from allauth.socialaccount.adapter import get_adapter from allauth.utils import get_request_param register = template.Library() @register.simple_tag(takes_context=True) def provider_login_url(context, provider, **params): """ {% provider_login_url "facebook" next=bla %} {% provider_login_url "openid" openid="http://me.yahoo.com" next=bla %} """ request = context.get("request") if isinstance(provider, str): adapter = get_adapter() provider = adapter.get_provider(request, provider) query = dict(params) auth_params = query.get("auth_params", None) scope = query.get("scope", None) process = query.get("process", None) if scope == "": del query["scope"] if auth_params == "": del query["auth_params"] if REDIRECT_FIELD_NAME not in query: next = get_request_param(request, REDIRECT_FIELD_NAME) if next: query[REDIRECT_FIELD_NAME] = next elif process == "redirect": query[REDIRECT_FIELD_NAME] = request.get_full_path() else: if not query[REDIRECT_FIELD_NAME]: del query[REDIRECT_FIELD_NAME] # get the login url and append query as url parameters return provider.get_login_url(request, **query) @register.simple_tag(takes_context=True) def providers_media_js(context): request = context["request"] providers = get_adapter().list_providers(request) ret = "\n".join(p.media_js(request) for p in providers) return mark_safe(ret) @register.simple_tag def get_social_accounts(user): """ {% get_social_accounts user as accounts %} Then: {{accounts.twitter}} -- a list of connected Twitter accounts {{accounts.twitter.0}} -- the first Twitter account {% if accounts %} -- if there is at least one social account """ accounts = {} for account in user.socialaccount_set.all().iterator(): providers = accounts.setdefault(account.provider, []) providers.append(account) return accounts @register.simple_tag(takes_context=True) def get_providers(context): """ Returns a list of social authentication providers. Usage: `{% get_providers as socialaccount_providers %}`. Then within the template context, `socialaccount_providers` will hold a list of social providers configured for the current site. """ request = context["request"] adapter = get_adapter() providers = adapter.list_providers(request) providers = [ provider for provider in providers if (not provider.uses_apps or not provider.app.settings.get("hidden")) ] return sorted(providers, key=lambda p: p.name) django-allauth-65.0.2/allauth/socialaccount/tests/000077500000000000000000000000001467545753200221435ustar00rootroot00000000000000django-allauth-65.0.2/allauth/socialaccount/tests/__init__.py000066400000000000000000000407461467545753200242670ustar00rootroot00000000000000import base64 import hashlib import json import random import requests import uuid import warnings from urllib.parse import parse_qs, urlparse from django.conf import settings from django.contrib.auth import get_user_model from django.test import RequestFactory from django.test.utils import override_settings from django.urls import reverse from django.utils.http import urlencode import allauth.app_settings from allauth.account.models import EmailAddress from allauth.account.utils import user_email, user_username from allauth.socialaccount import app_settings from allauth.socialaccount.adapter import get_adapter from allauth.socialaccount.models import SocialAccount, SocialApp from allauth.tests import MockedResponse, TestCase, mocked_response def setup_app(provider_id): request = RequestFactory().get("/") apps = get_adapter().list_apps(request, provider_id) if apps: return apps[0] app = SocialApp.objects.create( provider=provider_id, name=provider_id, client_id="app123id", key=provider_id, secret="dummy", ) if allauth.app_settings.SITES_ENABLED: from django.contrib.sites.models import Site app.sites.add(Site.objects.get_current()) return app class OAuthTestsMixin: provider_id: str def get_mocked_response(self): pass def get_expected_to_str(self): raise NotImplementedError def setUp(self): super(OAuthTestsMixin, self).setUp() self.app = setup_app(self.provider_id) request = RequestFactory().get("/") self.provider = self.app.get_provider(request) @override_settings(SOCIALACCOUNT_AUTO_SIGNUP=False) def test_login(self): resp_mocks = self.get_mocked_response() if resp_mocks is None: warnings.warn("Cannot test provider %s, no oauth mock" % self.provider.id) return resp = self.login(resp_mocks) self.assertRedirects(resp, reverse("socialaccount_signup")) resp = self.client.get(reverse("socialaccount_signup")) sociallogin = resp.context["form"].sociallogin data = dict( email=user_email(sociallogin.user), username=str(random.randrange(1000, 10000000)), ) resp = self.client.post(reverse("socialaccount_signup"), data=data) self.assertRedirects(resp, "/accounts/profile/", fetch_redirect_response=False) user = resp.context["user"] self.assertFalse(user.has_usable_password()) account = SocialAccount.objects.get(user=user, provider=self.provider.id) provider_account = account.get_provider_account() self.assertEqual(provider_account.to_str(), self.get_expected_to_str()) # The following lines don't actually test that much, but at least # we make sure that the code is hit. provider_account.get_avatar_url() provider_account.get_profile_url() provider_account.get_brand() @override_settings( SOCIALACCOUNT_AUTO_SIGNUP=True, SOCIALACCOUNT_EMAIL_REQUIRED=False, ACCOUNT_EMAIL_REQUIRED=False, ) def test_auto_signup(self): resp_mocks = self.get_mocked_response() if not resp_mocks: warnings.warn("Cannot test provider %s, no oauth mock" % self.provider.id) return resp = self.login(resp_mocks) self.assertRedirects(resp, "/accounts/profile/", fetch_redirect_response=False) self.assertFalse(resp.context["user"].has_usable_password()) def login(self, resp_mocks, process="login"): with mocked_response( MockedResponse( 200, "oauth_token=token&oauth_token_secret=psst", {"content-type": "text/html"}, ) ): resp = self.client.post( reverse(self.provider.id + "_login") + "?" + urlencode(dict(process=process)) ) p = urlparse(resp["location"]) q = parse_qs(p.query) complete_url = reverse(self.provider.id + "_callback") self.assertGreater(q["oauth_callback"][0].find(complete_url), 0) with mocked_response(self.get_access_token_response(), *resp_mocks): resp = self.client.get(complete_url) return resp def get_access_token_response(self): return MockedResponse( 200, "oauth_token=token&oauth_token_secret=psst", {"content-type": "text/html"}, ) def test_authentication_error(self): resp = self.client.get(reverse(self.provider.id + "_callback")) self.assertTemplateUsed( resp, "socialaccount/authentication_error.%s" % getattr(settings, "ACCOUNT_TEMPLATE_EXTENSION", "html"), ) # For backward-compatibility with third-party provider tests that call # create_oauth_tests() rather than using the mixin directly. def create_oauth_tests(provider): class Class(OAuthTestsMixin, TestCase): provider_id = provider.id Class.__name__ = "OAuthTests_" + provider.id return Class class OAuth2TestsMixin: provider_id: str def get_mocked_response(self): pass def get_expected_to_str(self): raise NotImplementedError def get_access_token(self) -> str: return "testac" def get_refresh_token(self) -> str: return "testrf" def get_login_response_json(self, with_refresh_token=True): response = { "uid": uuid.uuid4().hex, "access_token": self.get_access_token(), } if with_refresh_token: response["refresh_token"] = self.get_refresh_token() return json.dumps(response) def mocked_response(self, *responses): return mocked_response(*responses) def setUp(self): super(OAuth2TestsMixin, self).setUp() self.setup_provider() def setup_provider(self): self.app = setup_app(self.provider_id) self.request = RequestFactory().get("/") self.provider = self.app.get_provider(self.request) def test_provider_has_no_pkce_params(self): provider_settings = app_settings.PROVIDERS.get(self.app.provider, {}) provider_settings_with_pkce_set = provider_settings.copy() provider_settings_with_pkce_set["OAUTH_PKCE_ENABLED"] = False with self.settings( SOCIALACCOUNT_PROVIDERS={self.app.provider: provider_settings_with_pkce_set} ): self.assertEqual(self.provider.get_pkce_params(), {}) def test_provider_has_pkce_params(self): provider_settings = app_settings.PROVIDERS.get(self.app.provider, {}) provider_settings_with_pkce_set = provider_settings.copy() provider_settings_with_pkce_set["OAUTH_PKCE_ENABLED"] = True with self.settings( SOCIALACCOUNT_PROVIDERS={self.app.provider: provider_settings_with_pkce_set} ): pkce_params = self.provider.get_pkce_params() self.assertEqual( set(pkce_params.keys()), {"code_challenge", "code_challenge_method", "code_verifier"}, ) hashed_verifier = hashlib.sha256( pkce_params["code_verifier"].encode("ascii") ) code_challenge = base64.urlsafe_b64encode(hashed_verifier.digest()) code_challenge_without_padding = code_challenge.rstrip(b"=") assert pkce_params["code_challenge"] == code_challenge_without_padding @override_settings(SOCIALACCOUNT_AUTO_SIGNUP=False) def test_login(self): resp_mock = self.get_mocked_response() if not resp_mock: warnings.warn("Cannot test provider %s, no oauth mock" % self.provider.id) return resp = self.login( resp_mock, ) self.assertRedirects(resp, reverse("socialaccount_signup")) @override_settings(SOCIALACCOUNT_AUTO_SIGNUP=False) def test_login_with_pkce_disabled(self): provider_settings = app_settings.PROVIDERS.get(self.app.provider, {}) provider_settings_with_pkce_disabled = provider_settings.copy() provider_settings_with_pkce_disabled["OAUTH_PKCE_ENABLED"] = False with self.settings( SOCIALACCOUNT_PROVIDERS={ self.app.provider: provider_settings_with_pkce_disabled } ): resp_mock = self.get_mocked_response() if not resp_mock: warnings.warn( "Cannot test provider %s, no oauth mock" % self.provider.id ) return resp = self.login( resp_mock, ) self.assertRedirects(resp, reverse("socialaccount_signup")) @override_settings(SOCIALACCOUNT_AUTO_SIGNUP=False) def test_login_with_pkce_enabled(self): provider_settings = app_settings.PROVIDERS.get(self.app.provider, {}) provider_settings_with_pkce_enabled = provider_settings.copy() provider_settings_with_pkce_enabled["OAUTH_PKCE_ENABLED"] = True with self.settings( SOCIALACCOUNT_PROVIDERS={ self.app.provider: provider_settings_with_pkce_enabled } ): resp_mock = self.get_mocked_response() if not resp_mock: warnings.warn( "Cannot test provider %s, no oauth mock" % self.provider.id ) return resp = self.login( resp_mock, ) self.assertRedirects(resp, reverse("socialaccount_signup")) @override_settings(SOCIALACCOUNT_STORE_TOKENS=True) def test_account_tokens(self, multiple_login=False): email = "user@example.com" user = get_user_model()(is_active=True) user_email(user, email) user_username(user, "user") user.set_password("test") user.save() EmailAddress.objects.create(user=user, email=email, primary=True, verified=True) self.client.login(username=user.username, password="test") self.login(self.get_mocked_response(), process="connect") if multiple_login: self.login( self.get_mocked_response(), with_refresh_token=False, process="connect", ) # get account sa = SocialAccount.objects.filter( user=user, provider=self.provider.app.provider_id or self.provider.id ).get() provider_account = sa.get_provider_account() self.assertEqual(provider_account.to_str(), self.get_expected_to_str()) # The following lines don't actually test that much, but at least # we make sure that the code is hit. provider_account.get_avatar_url() provider_account.get_profile_url() provider_account.get_brand() # get token if self.app: t = sa.socialtoken_set.get() # verify access_token and refresh_token self.assertEqual(self.get_access_token(), t.token) resp = json.loads(self.get_login_response_json(with_refresh_token=True)) if "refresh_token" in resp: refresh_token = resp.get("refresh_token") elif "refreshToken" in resp: refresh_token = resp.get("refreshToken") else: refresh_token = "" self.assertEqual(t.token_secret, refresh_token) @override_settings(SOCIALACCOUNT_STORE_TOKENS=True) def test_account_refresh_token_saved_next_login(self): """ fails if a login missing a refresh token, deletes the previously saved refresh token. Systems such as google's oauth only send a refresh token on first login. """ self.test_account_tokens(multiple_login=True) def login(self, resp_mock=None, process="login", with_refresh_token=True): with self.mocked_response(): resp = self.client.post( self.provider.get_login_url(self.request, process=process) ) p = urlparse(resp["location"]) q = parse_qs(p.query) pkce_enabled = app_settings.PROVIDERS.get(self.app.provider, {}).get( "OAUTH_PKCE_ENABLED", self.provider.pkce_enabled_default ) self.assertEqual("code_challenge" in q, pkce_enabled) self.assertEqual("code_challenge_method" in q, pkce_enabled) if pkce_enabled: code_challenge = q["code_challenge"][0] self.assertEqual(q["code_challenge_method"][0], "S256") complete_url = self.provider.get_callback_url() self.assertGreater(q["redirect_uri"][0].find(complete_url), 0) response_json = self.get_login_response_json( with_refresh_token=with_refresh_token ) if isinstance(resp_mock, list): resp_mocks = resp_mock elif resp_mock is None: resp_mocks = [] else: resp_mocks = [resp_mock] with self.mocked_response( MockedResponse(200, response_json, {"content-type": "application/json"}), *resp_mocks, ): resp = self.client.get(complete_url, self.get_complete_parameters(q)) # Find the access token POST request, and assert that it contains # the correct code_verifier if and only if PKCE is enabled request_calls = requests.Session.request.call_args_list for args, kwargs in request_calls: data = kwargs.get("data", {}) if ( args[0] == "POST" and isinstance(data, dict) and data.get("redirect_uri", "").endswith(complete_url) ): self.assertEqual("code_verifier" in data, pkce_enabled) if pkce_enabled: hashed_code_verifier = hashlib.sha256( data["code_verifier"].encode("ascii") ) expected_code_challenge = ( base64.urlsafe_b64encode(hashed_code_verifier.digest()) .rstrip(b"=") .decode() ) self.assertEqual(code_challenge, expected_code_challenge) return resp def get_complete_parameters(self, q): return {"code": "test", "state": q["state"][0]} def test_authentication_error(self): resp = self.client.get(self.provider.get_callback_url()) self.assertTemplateUsed( resp, "socialaccount/authentication_error.%s" % getattr(settings, "ACCOUNT_TEMPLATE_EXTENSION", "html"), ) class OpenIDConnectTests(OAuth2TestsMixin): oidc_info_content = { "authorization_endpoint": "/login", "userinfo_endpoint": "/userinfo", "token_endpoint": "/token", } userinfo_content = { "picture": "https://secure.gravatar.com/avatar/123", "email": "ness@some.oidc.server.onett.example", "sub": 2187, "identities": [], "name": "Ness", } extra_data = { "picture": "https://secure.gravatar.com/avatar/123", "email": "ness@some.oidc.server.onett.example", "sub": 2187, "identities": [], "name": "Ness", } def mocked_response(self, *responses): return mocked_response(*responses, callback=self._mocked_responses) def get_expected_to_str(self): return "ness@some.oidc.server.onett.example" def setup_provider(self): self.app = setup_app(self.provider_id) self.app.provider_id = self.provider_id self.app.provider = "openid_connect" self.app.settings = { "server_url": "https://unittest.example.com", } self.app.save() self.request = RequestFactory().get("/") self.provider = self.app.get_provider(self.request) def get_mocked_response(self): # Enable test_login in OAuth2TestsMixin, but this response mock is unused return True def _mocked_responses(self, url, *args, **kwargs): if url.endswith("/.well-known/openid-configuration"): return MockedResponse(200, json.dumps(self.oidc_info_content)) elif url.endswith("/userinfo"): return MockedResponse(200, json.dumps(self.userinfo_content)) @override_settings(SOCIALACCOUNT_AUTO_SIGNUP=True) def test_login_auto_signup(self): resp = self.login() self.assertRedirects(resp, "/accounts/profile/", fetch_redirect_response=False) sa = SocialAccount.objects.get(provider=self.app.provider_id) self.assertDictEqual(sa.extra_data, self.extra_data) django-allauth-65.0.2/allauth/socialaccount/tests/conftest.py000066400000000000000000000021271467545753200243440ustar00rootroot00000000000000import time from django.urls import reverse import pytest from allauth.socialaccount.internal import statekit from allauth.socialaccount.providers.base.constants import AuthProcess from allauth.tests import MockedResponse, mocked_response @pytest.fixture def provider_callback_response(): def f(client, process=AuthProcess.LOGIN): with mocked_response( { "token_endpoint": "/", "userinfo_endpoint": "/", }, MockedResponse(200, "access_token=456", {"content-type": "dummy"}), { "sub": "sub123", }, ): session = client.session session[statekit.STATES_SESSION_KEY] = { "state456": [{"process": process}, time.time()] } session.save() resp = client.post( reverse( "openid_connect_callback", kwargs={"provider_id": "unittest-server"}, ) + "?code=123&state=state456" ) return resp return f django-allauth-65.0.2/allauth/socialaccount/tests/test_adapter.py000066400000000000000000000033711467545753200252000ustar00rootroot00000000000000from urllib.parse import parse_qs, urlparse from django.contrib.sites.models import Site from django.urls import reverse from allauth.socialaccount.adapter import ( DefaultSocialAccountAdapter, get_adapter, ) from allauth.socialaccount.internal import statekit from allauth.socialaccount.models import SocialApp class TestSocialAccountAdapter(DefaultSocialAccountAdapter): def generate_state_param(self, state: dict) -> str: return f"prefix-{super().generate_state_param(state)}" def test_generate_state_param(settings, client, db, google_provider_settings): settings.SOCIALACCOUNT_ADAPTER = ( "allauth.socialaccount.tests.test_adapter.TestSocialAccountAdapter" ) resp = client.post(reverse("google_login")) parsed = urlparse(resp["location"]) query = parse_qs(parsed.query) state = query["state"][0] assert len(state) == len("prefix-") + statekit.STATE_ID_LENGTH assert state.startswith("prefix-") def test_list_db_based_apps(db, settings): app = SocialApp.objects.create( provider="saml", provider_id="urn:idp-identity-id", client_id="org-slug" ) app.sites.add(Site.objects.get_current()) apps = get_adapter().list_apps(None, provider="saml", client_id="org-slug") assert app.pk in [a.pk for a in apps] def test_list_settings_based_apps(db, settings): settings.SOCIALACCOUNT_PROVIDERS = { "saml": { "APPS": [ { "provider_id": "urn:idp-entity-id", "client_id": "org-slug", } ] } } apps = get_adapter().list_apps(None, provider="saml", client_id="org-slug") assert len(apps) == 1 app = apps[0] assert not app.pk assert app.client_id == "org-slug" django-allauth-65.0.2/allauth/socialaccount/tests/test_connect.py000066400000000000000000000074471467545753200252210ustar00rootroot00000000000000from unittest.mock import patch from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.socialaccount.internal import flows from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.providers.base.constants import AuthProcess @pytest.mark.parametrize("reauthentication_required", [False, True]) def test_disconnect(auth_client, user, settings, mailoutbox, reauthentication_required): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True settings.ACCOUNT_REAUTHENTICATION_REQUIRED = reauthentication_required account_to_del = SocialAccount.objects.create( uid="123", provider="other-server", user=user ) account_to_keep = SocialAccount.objects.create( uid="456", provider="other-server", user=user ) resp = auth_client.get(reverse("socialaccount_connections")) assertTemplateUsed(resp, "socialaccount/connections.html") resp = auth_client.post( reverse("socialaccount_connections"), {"account": account_to_del.pk} ) if reauthentication_required: assert SocialAccount.objects.filter(pk=account_to_del.pk).exists() assert SocialAccount.objects.filter(pk=account_to_keep.pk).exists() else: assert not SocialAccount.objects.filter(pk=account_to_del.pk).exists() assert SocialAccount.objects.filter(pk=account_to_keep.pk).exists() assert len(mailoutbox) == 1 assert mailoutbox[0].subject == "[example.com] Third-Party Account Disconnected" def test_connect_with_reauthentication( auth_client, user, provider_callback_response, settings, user_password ): settings.ACCOUNT_REAUTHENTICATION_REQUIRED = True resp = provider_callback_response(auth_client, process="connect") assert not SocialAccount.objects.filter(user=user).exists() assert resp.status_code == 302 assert resp["location"] == reverse("account_reauthenticate") resp = auth_client.post(resp["location"], {"password": user_password}) assert resp.status_code == 302 assert resp["location"] == reverse("socialaccount_connections") assert SocialAccount.objects.filter(user=user).exists() def test_connect( auth_client, user, provider_callback_response, settings, user_password, mailoutbox ): settings.ACCOUNT_EMAIL_NOTIFICATIONS = True settings.ACCOUNT_REAUTHENTICATION_REQUIRED = False resp = provider_callback_response(auth_client, process="connect") assert resp.status_code == 302 assert SocialAccount.objects.filter(user=user).exists() assert resp["location"] == reverse("socialaccount_connections") assert len(mailoutbox) == 1 assert mailoutbox[0].subject == "[example.com] Third-Party Account Connected" @pytest.mark.parametrize( "email_authentication,account_exists, expected_action", [ (False, False, "added"), (False, True, "updated"), (True, False, "added"), (True, True, "updated"), ], ) def test_connect_vs_email_authentication( request_factory, sociallogin_factory, user, settings, email_authentication, account_exists, expected_action, ): settings.SOCIALACCOUNT_EMAIL_AUTHENTICATION = email_authentication sociallogin = sociallogin_factory(email=user.email, provider="unittest-server") if account_exists: account = sociallogin.account account.user = user account.save() sociallogin.state["process"] = AuthProcess.CONNECT request = request_factory.get("/") request.user = user with patch( "allauth.account.adapter.DefaultAccountAdapter.add_message" ) as add_message: flows.login.complete_login(request, sociallogin) assert add_message.call_args[1]["message_context"]["action"] == expected_action assert SocialAccount.objects.filter(user=user, uid=sociallogin.account.uid).exists() django-allauth-65.0.2/allauth/socialaccount/tests/test_login.py000066400000000000000000000122531467545753200246670ustar00rootroot00000000000000import copy from unittest.mock import ANY, patch from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.urls import reverse import pytest from pytest_django.asserts import assertTemplateUsed from allauth.account.authentication import AUTHENTICATION_METHODS_SESSION_KEY from allauth.core import context from allauth.socialaccount.helpers import complete_social_login from allauth.socialaccount.models import SocialAccount, SocialToken from allauth.socialaccount.providers.base import AuthProcess @pytest.mark.parametrize("with_emailaddress", [False, True]) @pytest.mark.parametrize("auto_connect", [False, True]) @pytest.mark.parametrize("setting", ["off", "on-global", "on-provider"]) def test_email_authentication( db, setting, settings, user_factory, sociallogin_factory, client, request_factory, mailoutbox, auto_connect, with_emailaddress, ): """Tests that when an already existing email is given at the social signup form, enumeration preventation kicks in. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.SOCIALACCOUNT_AUTO_SIGNUP = True settings.SOCIALACCOUNT_STORE_TOKENS = True if setting == "on-global": settings.SOCIALACCOUNT_EMAIL_AUTHENTICATION = True elif setting == "on-provider": settings.SOCIALACCOUNT_PROVIDERS = copy.deepcopy( settings.SOCIALACCOUNT_PROVIDERS ) settings.SOCIALACCOUNT_PROVIDERS["openid_connect"][ "EMAIL_AUTHENTICATION" ] = True else: settings.SOCIALACCOUNT_EMAIL_AUTHENTICATION = False settings.SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = auto_connect user = user_factory(with_emailaddress=with_emailaddress) assert user.has_usable_password() sociallogin = sociallogin_factory( email=user.email, provider="unittest-server", with_token=True ) request = request_factory.get("/") request.user = AnonymousUser() with context.request_context(request): with patch( "allauth.socialaccount.signals.social_account_updated.send" ) as updated_signal: with patch( "allauth.socialaccount.signals.social_account_added.send" ) as added_signal: resp = complete_social_login(request, sociallogin) user.refresh_from_db() if setting == "off": assert resp["location"] == reverse("account_email_verification_sent") assert not added_signal.called assert not updated_signal.called else: if with_emailaddress: assert resp["location"] == "/accounts/profile/" assert user.has_usable_password() else: assert not user.has_usable_password() # This should be improved. The provider vouches for the fact that # the user verified the email, so we can mark it as such locally as # well. # user.email is set, but not verified. assert resp["location"] == reverse("account_email_verification_sent") assert get_user_model().objects.count() == 1 assert SocialAccount.objects.filter(user=user.pk).exists() == auto_connect assert ( SocialToken.objects.filter(account__user=user.pk).exists() == auto_connect ) assert added_signal.called == auto_connect assert not updated_signal.called def test_login_cancelled(client): resp = client.get(reverse("socialaccount_login_cancelled")) assert resp.status_code == 200 assertTemplateUsed(resp, "socialaccount/login_cancelled.html") @pytest.mark.parametrize("store_tokens", [False, True]) @pytest.mark.parametrize( "process,did_record", [ (AuthProcess.LOGIN, True), (AuthProcess.CONNECT, False), ], ) def test_record_authentication( db, sociallogin_factory, client, request_factory, user, process, did_record, store_tokens, settings, ): settings.SOCIALACCOUNT_STORE_TOKENS = store_tokens sociallogin = sociallogin_factory(provider="unittest-server", uid="123") sociallogin.state["process"] = process sociallogin.token = SocialToken( app=sociallogin.account.get_provider().app, token="123", token_secret="456" ) SocialAccount.objects.create(user=user, uid="123", provider="unittest-server") request = request_factory.get("/") request.user = AnonymousUser() with context.request_context(request): complete_social_login(request, sociallogin) if did_record: assert request.session[AUTHENTICATION_METHODS_SESSION_KEY] == [ { "at": ANY, "provider": sociallogin.account.provider, "method": "socialaccount", "uid": "123", } ] else: assert AUTHENTICATION_METHODS_SESSION_KEY not in request.session assert ( SocialToken.objects.filter( account__uid="123", token="123", token_secret="456" ).exists() == store_tokens ) django-allauth-65.0.2/allauth/socialaccount/tests/test_registry.py000066400000000000000000000037411467545753200254310ustar00rootroot00000000000000from django.apps import AppConfig, apps from django.test.utils import override_settings from allauth.socialaccount import providers from allauth.tests import TestCase class CustomFacebookAppConfig(AppConfig): name = "allauth.socialaccount.providers.facebook" label = "allauth_facebook" class ProviderRegistryTests(TestCase): @override_settings( INSTALLED_APPS=[ "allauth.socialaccount.providers.facebook", ] ) def test_load_provider_with_default_app_config(self): registry = providers.ProviderRegistry() provider_list = registry.get_class_list() self.assertTrue(registry.loaded) self.assertEqual(1, len(provider_list)) self.assertTrue( issubclass( provider_list[0], providers.facebook.provider.FacebookProvider, ) ) app_config_list = list(apps.get_app_configs()) self.assertEqual(1, len(app_config_list)) app_config = app_config_list[0] self.assertEqual("allauth.socialaccount.providers.facebook", app_config.name) self.assertEqual("facebook", app_config.label) @override_settings( INSTALLED_APPS=[ "allauth.socialaccount.tests.test_registry.CustomFacebookAppConfig", ] ) def test_load_provider_with_custom_app_config(self): registry = providers.ProviderRegistry() provider_list = registry.get_class_list() self.assertTrue(registry.loaded) self.assertEqual(1, len(provider_list)) self.assertTrue( issubclass( provider_list[0], providers.facebook.provider.FacebookProvider, ) ) app_config_list = list(apps.get_app_configs()) self.assertEqual(1, len(app_config_list)) app_config = app_config_list[0] self.assertEqual("allauth.socialaccount.providers.facebook", app_config.name) self.assertEqual("allauth_facebook", app_config.label) django-allauth-65.0.2/allauth/socialaccount/tests/test_signup.py000066400000000000000000000413111467545753200250610ustar00rootroot00000000000000from unittest.mock import patch from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.urls import reverse import pytest from pytest_django.asserts import assertFormError, assertRedirects from allauth.account import app_settings as account_settings from allauth.account.models import EmailAddress from allauth.account.utils import user_email, user_username from allauth.core import context from allauth.socialaccount.helpers import complete_social_login from allauth.socialaccount.models import SocialAccount, SocialLogin from allauth.socialaccount.views import signup @pytest.fixture def setup_sociallogin_flow(request_factory): def f(client, sociallogin): request = request_factory.get("/") request.user = AnonymousUser() with context.request_context(request): resp = complete_social_login(request, sociallogin) session = client.session for k, v in request.session.items(): session[k] = v session.save() return resp return f @pytest.fixture def email_address_clash(request_factory): def _email_address_clash(username, email): User = get_user_model() # Some existig user exi_user = User() user_username(exi_user, "test") exi_user_email = "test@example.com" user_email(exi_user, exi_user_email) exi_user.save() EmailAddress.objects.create( user=exi_user, email=exi_user_email, verified=True, primary=True ) # A social user being signed up... account = SocialAccount(provider="twitter", uid="123") user = User() user_username(user, username) user_email(user, email) sociallogin = SocialLogin( user=user, account=account, email_addresses=[EmailAddress(email=email)] ) # Signing up, should pop up the social signup form request = request_factory.get("/accounts/twitter/login/callback/") request.user = AnonymousUser() with context.request_context(request): resp = complete_social_login(request, sociallogin) return request, resp return _email_address_clash def test_email_address_created( settings, db, client, setup_sociallogin_flow, sociallogin_factory ): settings.SOCIALACCOUNT_AUTO_SIGNUP = True settings.ACCOUNT_SIGNUP_FORM_CLASS = None settings.ACCOUNT_EMAIL_VERIFICATION = account_settings.EmailVerificationMethod.NONE sociallogin = sociallogin_factory( email="test@example.com", email_verified=False, username="test" ) setup_sociallogin_flow(client, sociallogin) user = get_user_model().objects.get( **{account_settings.USER_MODEL_USERNAME_FIELD: "test"} ) assert SocialAccount.objects.filter(user=user, uid=sociallogin.account.uid).exists() assert EmailAddress.objects.filter(user=user, email=user_email(user)).exists() def test_email_address_clash_username_required( db, client, settings, email_address_clash ): """Test clash on both username and email""" settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = True settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = True request, resp = email_address_clash("test", "test@example.com") assert resp["location"] == reverse("socialaccount_signup") # POST different username/email to social signup form request.method = "POST" request.POST = {"username": "other", "email": "other@example.com"} with context.request_context(request): resp = signup(request) assert resp["location"] == "/accounts/profile/" user = get_user_model().objects.get( **{account_settings.USER_MODEL_EMAIL_FIELD: "other@example.com"} ) assert user_username(user) == "other" def test_email_address_clash_username_not_required(db, settings, email_address_clash): """Test clash while username is not required""" settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = True request, resp = email_address_clash("test", "test@example.com") assert resp["location"] == reverse("socialaccount_signup") # POST email to social signup form (username not present) request.method = "POST" request.POST = {"email": "other@example.com"} with context.request_context(request): resp = signup(request) assert resp["location"] == "/accounts/profile/" user = get_user_model().objects.get( **{account_settings.USER_MODEL_EMAIL_FIELD: "other@example.com"} ) assert user_username(user) != "test" def test_email_address_clash_username_auto_signup(db, settings, email_address_clash): settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = True # Clash on username, but auto signup still works request, resp = email_address_clash("test", "other@example.com") assert resp["location"] == "/accounts/profile/" user = get_user_model().objects.get( **{account_settings.USER_MODEL_EMAIL_FIELD: "other@example.com"} ) assert user_username(user) != "test" def test_populate_username_in_blacklist(db, settings, request_factory): settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_USERNAME_BLACKLIST = ["username", "username1", "username2"] settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = True settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = True request = request_factory.get("/accounts/twitter/login/callback/") request.user = AnonymousUser() User = get_user_model() user = User() setattr(user, account_settings.USER_MODEL_USERNAME_FIELD, "username") setattr( user, account_settings.USER_MODEL_EMAIL_FIELD, "username@example.com", ) account = SocialAccount(provider="twitter", uid="123") sociallogin = SocialLogin(user=user, account=account) with context.request_context(request): complete_social_login(request, sociallogin) assert request.user.username not in account_settings.USERNAME_BLACKLIST def test_verified_email_change_at_signup( db, client, settings, sociallogin_factory, setup_sociallogin_flow ): """ Test scenario for when the user changes email at social signup. Current behavior is that both the unverified and verified email are added, and that the user is allowed to pass because he did provide a verified one. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = False sociallogin = sociallogin_factory(email="verified@example.com") setup_sociallogin_flow(client, sociallogin) resp = client.get(reverse("socialaccount_signup")) form = resp.context["form"] assert form["email"].value() == "verified@example.com" resp = client.post( reverse("socialaccount_signup"), data={"email": "unverified@example.org"}, ) assertRedirects(resp, "/accounts/profile/", fetch_redirect_response=False) user = get_user_model().objects.all()[0] assert user_email(user) == "verified@example.com" assert EmailAddress.objects.filter( user=user, email="verified@example.com", verified=True, primary=True, ).exists() assert EmailAddress.objects.filter( user=user, email="unverified@example.org", verified=False, primary=False, ).exists() def test_unverified_email_change_at_signup( db, client, settings, sociallogin_factory, setup_sociallogin_flow ): """ Test scenario for when the user changes email at social signup, while his provider did not provide a verified email. In that case, email verification will kick in. Here, both email addresses are added as well. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = False User = get_user_model() sociallogin = sociallogin_factory( email="unverified@example.com", email_verified=False ) setup_sociallogin_flow(client, sociallogin) resp = client.get(reverse("socialaccount_signup")) form = resp.context["form"] assert form["email"].value() == "unverified@example.com" resp = client.post( reverse("socialaccount_signup"), data={"email": "unverified@example.org"}, ) assertRedirects(resp, reverse("account_email_verification_sent")) user = User.objects.all()[0] assert user_email(user) == "unverified@example.org" assert EmailAddress.objects.filter( user=user, email="unverified@example.com", verified=False, primary=False, ).exists() assert EmailAddress.objects.filter( user=user, email="unverified@example.org", verified=False, primary=True, ).exists() def test_unique_email_validation_signup( db, client, sociallogin_factory, settings, setup_sociallogin_flow ): settings.ACCOUNT_PREVENT_ENUMERATION = False settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = False User = get_user_model() email = "me@example.com" user = User.objects.create(email=email) EmailAddress.objects.create(email=email, user=user, verified=True) sociallogin = sociallogin_factory(email="me@example.com") setup_sociallogin_flow(client, sociallogin) resp = client.get(reverse("socialaccount_signup")) form = resp.context["form"] assert form["email"].value() == email resp = client.post(reverse("socialaccount_signup"), data={"email": email}) assertFormError( resp.context["form"], "email", "An account already exists with this email address." " Please sign in to that account first, then connect" " your Unittest Server account.", ) def test_social_account_taken_at_signup( db, client, sociallogin_factory, settings, setup_sociallogin_flow ): """ Test scenario for when the user signs up with a social account and uses email address in that social account. But upon seeing the verification screen, they realize that email address is somehow unusable for them, and so backs up and enters a different email address (and is forced to choose a new username) while providing the same social account token which is owned by their first attempt. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = True settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.SOCIALACCOUNT_AUTO_SIGNUP = False User = get_user_model() sociallogin = sociallogin_factory(email="me1@example.com", email_verified=False) setup_sociallogin_flow(client, sociallogin) resp = client.get(reverse("socialaccount_signup")) form = resp.context["form"] assert form["email"].value() == "me1@example.com" resp = client.post( reverse("socialaccount_signup"), data={"username": "me1", "email": "me1@example.com"}, ) assert resp.status_code == 302 assert User.objects.count() == 1 assert SocialAccount.objects.count() == 1 resp = client.get(reverse("socialaccount_signup")) assertRedirects(resp, reverse("account_login")) def test_email_address_required_missing_from_sociallogin( db, settings, sociallogin_factory, client, setup_sociallogin_flow ): """Tests that when the email address is missing from the sociallogin email verification kicks in. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.SOCIALACCOUNT_AUTO_SIGNUP = True sociallogin = sociallogin_factory(with_email=False) resp = setup_sociallogin_flow(client, sociallogin) assert resp["location"] == reverse("socialaccount_signup") resp = client.post(reverse("socialaccount_signup"), {"email": "other@example.org"}) assert resp["location"] == reverse("account_email_verification_sent") def test_email_address_conflict_at_social_signup_form( db, settings, user_factory, sociallogin_factory, client, setup_sociallogin_flow, mailoutbox, ): """Tests that when an already existing email is given at the social signup form, enumeration preventation kicks in. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.SOCIALACCOUNT_AUTO_SIGNUP = True user = user_factory() sociallogin = sociallogin_factory(with_email=False) resp = setup_sociallogin_flow(client, sociallogin) # Auto signup does not kick in as the `sociallogin` does not have an email. assert resp["location"] == reverse("socialaccount_signup") # Here, we input the already existing email. resp = client.post(reverse("socialaccount_signup"), {"email": user.email}) assert mailoutbox[0].subject == "[example.com] Account Already Exists" assert resp["location"] == reverse("account_email_verification_sent") def test_email_address_conflict_during_auto_signup( db, settings, user_factory, sociallogin_factory, client, mailoutbox, setup_sociallogin_flow, ): """Tests that when an already existing email is received from the provider, enumeration preventation kicks in. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "mandatory" settings.SOCIALACCOUNT_AUTO_SIGNUP = True user = user_factory() sociallogin = sociallogin_factory(email=user.email, with_email=True) resp = setup_sociallogin_flow(client, sociallogin) assert resp["location"] == reverse("account_email_verification_sent") assert mailoutbox[0].subject == "[example.com] Account Already Exists" def test_email_address_conflict_removes_conflicting_email( db, settings, user_factory, sociallogin_factory, client, mailoutbox, setup_sociallogin_flow, ): """Tests that when an already existing email is given at the social signup form, enumeration preventation kicks in. """ settings.ACCOUNT_EMAIL_REQUIRED = True settings.ACCOUNT_UNIQUE_EMAIL = True settings.ACCOUNT_USERNAME_REQUIRED = False settings.ACCOUNT_AUTHENTICATION_METHOD = "email" settings.ACCOUNT_EMAIL_VERIFICATION = "optional" settings.SOCIALACCOUNT_AUTO_SIGNUP = True settings.SOCIALACCOUNT_EMAIL_AUTHENTICATION = False user = user_factory(email_verified=False) sociallogin = sociallogin_factory(email=user.email, email_verified=False) resp = setup_sociallogin_flow(client, sociallogin) # Auto signup does not kick in as the `sociallogin` has a conflicting email. assert resp["location"] == reverse("socialaccount_signup") # Here, we input the already existing email. resp = client.post(reverse("socialaccount_signup"), {"email": "other@email.org"}) assert mailoutbox[0].subject == "[example.com] Please Confirm Your Email Address" assert resp["location"] == settings.LOGIN_REDIRECT_URL assert EmailAddress.objects.filter(email=user.email).count() == 1 def test_signup_closed( settings, db, client, setup_sociallogin_flow, sociallogin_factory, ): sociallogin = sociallogin_factory( email="test@example.com", email_verified=False, username="test" ) with patch( "allauth.socialaccount.adapter.DefaultSocialAccountAdapter.is_open_for_signup" ) as iofs: iofs.return_value = False resp = setup_sociallogin_flow(client, sociallogin) assert b"Sign Up Closed" in resp.content assert not get_user_model().objects.exists() django-allauth-65.0.2/allauth/socialaccount/tests/test_utils.py000066400000000000000000000015511467545753200247160ustar00rootroot00000000000000from django.contrib.auth import get_user_model from django.test.utils import override_settings from allauth.socialaccount.models import SocialAccount from allauth.tests import TestCase class UtilTests(TestCase): def test_social_account_str_default(self): User = get_user_model() user = User(username="test") sa = SocialAccount(user=user) self.assertEqual("test", str(sa)) def socialaccount_str_custom_formatter(socialaccount): return "A custom str builder for {}".format(socialaccount.user) @override_settings( SOCIALACCOUNT_SOCIALACCOUNT_STR=socialaccount_str_custom_formatter ) def test_social_account_str_customized(self): User = get_user_model() user = User(username="test") sa = SocialAccount(user=user) self.assertEqual("A custom str builder for test", str(sa)) django-allauth-65.0.2/allauth/socialaccount/urls.py000066400000000000000000000006221467545753200223400ustar00rootroot00000000000000from django.urls import path from . import views urlpatterns = [ path( "login/cancelled/", views.login_cancelled, name="socialaccount_login_cancelled", ), path("login/error/", views.login_error, name="socialaccount_login_error"), path("signup/", views.signup, name="socialaccount_signup"), path("", views.connections, name="socialaccount_connections"), ] django-allauth-65.0.2/allauth/socialaccount/views.py000066400000000000000000000077031467545753200225170ustar00rootroot00000000000000from django.contrib.auth.decorators import login_required from django.contrib.sites.shortcuts import get_current_site from django.http import HttpResponseRedirect from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator from django.views.generic.base import TemplateView from django.views.generic.edit import FormView from allauth.account.internal.decorators import login_not_required from allauth.socialaccount.forms import DisconnectForm, SignupForm from allauth.socialaccount.internal import flows from allauth.socialaccount.models import SocialAccount from ..account import app_settings as account_settings from ..account.views import ( AjaxCapableProcessFormViewMixin, CloseableSignupMixin, RedirectAuthenticatedUserMixin, ) from ..utils import get_form_class from . import app_settings from .adapter import get_adapter class SignupView( RedirectAuthenticatedUserMixin, CloseableSignupMixin, AjaxCapableProcessFormViewMixin, FormView, ): form_class = SignupForm template_name = "socialaccount/signup." + account_settings.TEMPLATE_EXTENSION def get_form_class(self): return get_form_class(app_settings.FORMS, "signup", self.form_class) @method_decorator(login_not_required) def dispatch(self, request, *args, **kwargs): self.sociallogin = flows.signup.get_pending_signup(request) if not self.sociallogin: return HttpResponseRedirect(reverse("account_login")) return super(SignupView, self).dispatch(request, *args, **kwargs) def is_open(self): return get_adapter(self.request).is_open_for_signup( self.request, self.sociallogin ) def get_form_kwargs(self): ret = super(SignupView, self).get_form_kwargs() ret["sociallogin"] = self.sociallogin return ret def form_valid(self, form): return flows.signup.signup_by_form(self.request, self.sociallogin, form) def get_context_data(self, **kwargs): ret = super(SignupView, self).get_context_data(**kwargs) ret.update( dict( site=get_current_site(self.request), account=self.sociallogin.account, ) ) return ret def get_authenticated_redirect_url(self): return reverse("socialaccount_connections") signup = SignupView.as_view() @method_decorator(login_not_required, name="dispatch") class LoginCancelledView(TemplateView): template_name = ( "socialaccount/login_cancelled." + account_settings.TEMPLATE_EXTENSION ) login_cancelled = LoginCancelledView.as_view() class LoginErrorView(TemplateView): template_name = ( "socialaccount/authentication_error." + account_settings.TEMPLATE_EXTENSION ) login_error = LoginErrorView.as_view() @method_decorator(login_required, name="dispatch") class ConnectionsView(AjaxCapableProcessFormViewMixin, FormView): template_name = "socialaccount/connections." + account_settings.TEMPLATE_EXTENSION form_class = DisconnectForm success_url = reverse_lazy("socialaccount_connections") def get_form_class(self): return get_form_class(app_settings.FORMS, "disconnect", self.form_class) def get_form_kwargs(self): kwargs = super(ConnectionsView, self).get_form_kwargs() kwargs["request"] = self.request return kwargs def form_valid(self, form): form.save() return super(ConnectionsView, self).form_valid(form) def get_ajax_data(self): account_data = [] for account in SocialAccount.objects.filter(user=self.request.user): provider_account = account.get_provider_account() account_data.append( { "id": account.pk, "provider": account.provider, "name": provider_account.to_str(), } ) return {"socialaccounts": account_data} connections = ConnectionsView.as_view() django-allauth-65.0.2/allauth/templates/000077500000000000000000000000001467545753200201505ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/account/000077500000000000000000000000001467545753200216045ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/account/account_inactive.html000066400000000000000000000006061467545753200260120ustar00rootroot00000000000000{% extends "allauth/layouts/entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% translate "Account Inactive" %} {% endblock head_title %} {% block content %} {% element h1 %} {% translate "Account Inactive" %} {% endelement %} {% element p %} {% translate "This account is inactive." %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/base_entrance.html000066400000000000000000000000561467545753200252640ustar00rootroot00000000000000{% extends "allauth/layouts/entrance.html" %} django-allauth-65.0.2/allauth/templates/account/base_manage.html000066400000000000000000000000541467545753200247130ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} django-allauth-65.0.2/allauth/templates/account/base_manage_email.html000066400000000000000000000000511467545753200260570ustar00rootroot00000000000000{% extends "account/base_manage.html" %} django-allauth-65.0.2/allauth/templates/account/base_manage_password.html000066400000000000000000000000511467545753200266320ustar00rootroot00000000000000{% extends "account/base_manage.html" %} django-allauth-65.0.2/allauth/templates/account/base_reauthenticate.html000066400000000000000000000017211467545753200264720ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load allauth %} {% load i18n %} {% block head_title %} {% trans "Confirm Access" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Confirm Access" %} {% endelement %} {% element p %} {% blocktranslate %}Please reauthenticate to safeguard your account.{% endblocktranslate %} {% endelement %} {% block reauthenticate_content %}{% endblock %} {% if reauthentication_alternatives %} {% element hr %} {% endelement %} {% element h2 %} {% translate "Alternative options" %} {% endelement %} {% element button_group %} {% for alt in reauthentication_alternatives %} {% element button href=alt.url tags="primary,outline" %} {{ alt.description }} {% endelement %} {% endfor %} {% endelement %} {% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/confirm_email_verification_code.html000066400000000000000000000035031467545753200310330ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth account %} {% block head_title %} {% translate "Email Verification" %} {% endblock head_title %} {% block content %} {% element h1 %} {% translate "Enter Email Verification Code" %} {% endelement %} {% setvar email_link %} {{ email }} {% endsetvar %} {% element p %} {% blocktranslate %}We’ve sent a code to {{ email_link }}. The code expires shortly, so please enter it soon.{% endblocktranslate %} {% endelement %} {% url 'account_email_verification_sent' as action_url %} {% element form form=form method="post" action=action_url tags="entrance,email,verification" %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" tags="prominent,confirm" %} {% translate "Confirm" %} {% endelement %} {% if cancel_url %} {% element button href=cancel_url tags="link,cancel" %} {% translate "Cancel" %} {% endelement %} {% else %} {% element button type="submit" form="logout-from-stage" tags="link,cancel" %} {% translate "Cancel" %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% if not cancel_url %}
{% csrf_token %}
{% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/confirm_login_code.html000066400000000000000000000027031467545753200263130ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth account %} {% block head_title %} {% translate "Sign In" %} {% endblock head_title %} {% block content %} {% element h1 %} {% translate "Enter Sign-In Code" %} {% endelement %} {% setvar email_link %} {{ email }} {% endsetvar %} {% element p %} {% blocktranslate %}We’ve sent a code to {{ email_link }}. The code expires shortly, so please enter it soon.{% endblocktranslate %} {% endelement %} {% url 'account_confirm_login_code' as login_url %} {% element form form=form method="post" action=login_url tags="entrance,login" %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" tags="prominent,login" %} {% translate "Sign In" %} {% endelement %} {% endslot %} {% endelement %} {% element button type="submit" form="logout-from-stage" tags="link" %} {% translate "Cancel" %} {% endelement %}
{% csrf_token %}
{% endblock content %} django-allauth-65.0.2/allauth/templates/account/email.html000066400000000000000000000072671467545753200235750ustar00rootroot00000000000000{% extends "account/base_manage_email.html" %} {% load allauth i18n %} {% block head_title %} {% trans "Email Addresses" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Email Addresses" %} {% endelement %} {% if emailaddresses %} {% element p %} {% trans 'The following email addresses are associated with your account:' %} {% endelement %} {% url 'account_email' as email_url %} {% element form form=form action=email_url method="post" tags="email,list" %} {% slot body %} {% csrf_token %} {% for radio in emailaddress_radios %} {% with emailaddress=radio.emailaddress %} {% element field type="radio" checked=radio.checked name="email" value=emailaddress.email id=radio.id %} {% slot label %} {{ emailaddress.email }} {% if emailaddress.verified %} {% element badge tags="success,email,verified" %} {% translate "Verified" %} {% endelement %} {% else %} {% element badge tags="warning,email,unverified" %} {% translate "Unverified" %} {% endelement %} {% endif %} {% if emailaddress.primary %} {% element badge tags="email,primary" %} {% translate "Primary" %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% endwith %} {% endfor %} {% endslot %} {% slot actions %} {% element button type="submit" name="action_primary" %} {% trans 'Make Primary' %} {% endelement %} {% element button tags="secondary" type="submit" name="action_send" %} {% trans 'Re-send Verification' %} {% endelement %} {% element button tags="danger,delete" type="submit" name="action_remove" %} {% trans 'Remove' %} {% endelement %} {% endslot %} {% endelement %} {% else %} {% include "account/snippets/warn_no_email.html" %} {% endif %} {% if can_add_email %} {% element h2 %} {% trans "Add Email Address" %} {% endelement %} {% url 'account_email' as action_url %} {% element form form=form method="post" action=action_url tags="email,add" %} {% slot body %} {% csrf_token %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button name="action_add" type="submit" %} {% trans "Add Email" %} {% endelement %} {% endslot %} {% endelement %} {% endif %} {% endblock content %} {% block extra_body %} {% endblock extra_body %} django-allauth-65.0.2/allauth/templates/account/email/000077500000000000000000000000001467545753200226735ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/account/email/account_already_exists_message.txt000066400000000000000000000007621467545753200317010ustar00rootroot00000000000000{% extends "account/email/base_message.txt" %} {% load i18n %} {% block content %}{% autoescape off %}{% blocktrans %}You are receiving this email because you or someone else tried to signup for an account using email address: {{ email }} However, an account using that email address already exists. In case you have forgotten about this, please use the password forgotten procedure to recover your account: {{ password_reset_url }}{% endblocktrans %}{% endautoescape %}{% endblock content %} django-allauth-65.0.2/allauth/templates/account/email/account_already_exists_subject.txt000066400000000000000000000001631467545753200317070ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Account Already Exists{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/base_message.txt000066400000000000000000000005361467545753200260560ustar00rootroot00000000000000{% load i18n %}{% autoescape off %}{% blocktrans with site_name=current_site.name %}Hello from {{ site_name }}!{% endblocktrans %} {% block content %}{% endblock content %} {% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you for using {{ site_name }}! {{ site_domain }}{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/base_notification.txt000066400000000000000000000011121467545753200271070ustar00rootroot00000000000000{% extends "account/email/base_message.txt" %} {% load account %} {% load i18n %} {% block content %}{% autoescape off %}{% blocktrans %}You are receiving this mail because the following change was made to your account:{% endblocktrans %} {% block notification_message %} {% endblock notification_message%} {% blocktrans %}If you do not recognize this change then please take proper security precautions immediately. The change to your account originates from: - IP address: {{ip}} - Browser: {{user_agent}} - Date: {{timestamp}}{% endblocktrans %}{% endautoescape %}{% endblock %} django-allauth-65.0.2/allauth/templates/account/email/email_changed_message.txt000066400000000000000000000003601467545753200276770ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Your email has been changed from {{ from_email }} to {{ to_email }}.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/account/email/email_changed_subject.txt000066400000000000000000000001521467545753200277110ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Email Changed{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/email_confirm_message.txt000066400000000000000000000003121467545753200277400ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Your email has been confirmed.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/account/email/email_confirm_subject.txt000066400000000000000000000001571467545753200277620ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Email Confirmation{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/email_confirmation_message.txt000066400000000000000000000013201467545753200307730ustar00rootroot00000000000000{% extends "account/email/base_message.txt" %} {% load account %} {% load i18n %} {% block content %}{% autoescape off %}{% user_display user as user_display %}{% blocktranslate with site_name=current_site.name site_domain=current_site.domain %}You're receiving this email because user {{ user_display }} has given your email address to register an account on {{ site_domain }}.{% endblocktranslate %} {% if code %}{% blocktranslate %}Your email verification code is listed below. Please enter it in your open browser window.{% endblocktranslate %} {{ code }}{% else %}{% blocktranslate %}To confirm this is correct, go to {{ activate_url }}{% endblocktranslate %}{% endif %}{% endautoescape %}{% endblock content %} django-allauth-65.0.2/allauth/templates/account/email/email_confirmation_signup_message.txt000066400000000000000000000000751467545753200323660ustar00rootroot00000000000000{% include "account/email/email_confirmation_message.txt" %} django-allauth-65.0.2/allauth/templates/account/email/email_confirmation_signup_subject.txt000066400000000000000000000000751467545753200324010ustar00rootroot00000000000000{% include "account/email/email_confirmation_subject.txt" %} django-allauth-65.0.2/allauth/templates/account/email/email_confirmation_subject.txt000066400000000000000000000001761467545753200310160ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Please Confirm Your Email Address{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/email_deleted_message.txt000066400000000000000000000003611467545753200277150ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Email address {{ deleted_email }} has been removed from your account.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/account/email/email_deleted_subject.txt000066400000000000000000000001521467545753200277260ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Email Removed{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/login_code_message.txt000066400000000000000000000006331467545753200272440ustar00rootroot00000000000000{% extends "account/email/base_message.txt" %} {% load account %} {% load i18n %} {% block content %}{% autoescape off %}{% blocktranslate %}Your sign-in code is listed below. Please enter it in your open browser window.{% endblocktranslate %}{% endautoescape %} {{ code }} {% blocktranslate %}This mail can be safely ignored if you did not initiate this action.{% endblocktranslate %}{% endblock content %} django-allauth-65.0.2/allauth/templates/account/email/login_code_subject.txt000066400000000000000000000001511467545753200272520ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Sign-In Code{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/password_changed_message.txt000066400000000000000000000003131467545753200304500ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Your password has been changed.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/account/email/password_changed_subject.txt000066400000000000000000000001551467545753200304670ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Password Changed{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/password_reset_key_message.txt000066400000000000000000000010371467545753200310550ustar00rootroot00000000000000{% extends "account/email/base_message.txt" %} {% load i18n %} {% block content %}{% autoescape off %}{% blocktrans %}You're receiving this email because you or someone else has requested a password reset for your user account. It can be safely ignored if you did not request a password reset. Click the link below to reset your password.{% endblocktrans %} {{ password_reset_url }}{% if username %} {% blocktrans %}In case you forgot, your username is {{ username }}.{% endblocktrans %}{% endif %}{% endautoescape %}{% endblock content %} django-allauth-65.0.2/allauth/templates/account/email/password_reset_key_subject.txt000066400000000000000000000001611467545753200310650ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Password Reset Email{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/password_reset_message.txt000066400000000000000000000003111467545753200301770ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Your password has been reset.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/account/email/password_reset_subject.txt000066400000000000000000000001531467545753200302160ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Password Reset{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/password_set_message.txt000066400000000000000000000003071467545753200276550ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Your password has been set.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/account/email/password_set_subject.txt000066400000000000000000000001511467545753200276650ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Password Set{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email/unknown_account_message.txt000066400000000000000000000011431467545753200303520ustar00rootroot00000000000000{% extends "account/email/base_message.txt" %} {% load i18n %} {% block content %}{% autoescape off %}{% blocktranslate %}You are receiving this email because you, or someone else, tried to access an account with email {{ email }}. However, we do not have any record of such an account in our database.{% endblocktranslate %} {% blocktranslate %}This mail can be safely ignored if you did not initiate this action.{% endblocktranslate %} {% blocktranslate %}If it was you, you can sign up for an account using the link below.{% endblocktranslate %} {{ signup_url }}{% endautoescape %}{% endblock content %} django-allauth-65.0.2/allauth/templates/account/email/unknown_account_subject.txt000066400000000000000000000001541467545753200303660ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Unknown Account{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/account/email_change.html000066400000000000000000000056261467545753200250770ustar00rootroot00000000000000{% extends "account/base_manage_email.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Email Address" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Email Address" %} {% endelement %} {% if not emailaddresses %} {% include "account/snippets/warn_no_email.html" %} {% endif %} {% url 'account_email' as action_url %} {% element form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% if current_emailaddress %} {% element field id="current_email" disabled=True type="email" value=current_emailaddress.email %} {% slot label %} {% translate "Current email" %}: {% endslot %} {% endelement %} {% endif %} {% if new_emailaddress %} {% element field id="new_email" value=new_emailaddress.email disabled=True type="email" %} {% slot label %} {% if not current_emailaddress %} {% translate "Current email" %}: {% else %} {% translate "Changing to" %}: {% endif %} {% endslot %} {% slot help_text %} {% blocktranslate %}Your email address is still pending verification.{% endblocktranslate %} {% element button form="pending-email" type="submit" name="action_send" tags="minor,secondary" %} {% trans 'Re-send Verification' %} {% endelement %} {% if current_emailaddress %} {% element button form="pending-email" type="submit" name="action_remove" tags="danger,minor" %} {% trans 'Cancel Change' %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% endif %} {% element field id=form.email.auto_id name="email" value=form.email.value errors=form.email.errors type="email" %} {% slot label %} {% translate "Change to" %}: {% endslot %} {% endelement %} {% endslot %} {% slot actions %} {% element button name="action_add" type="submit" %} {% trans "Change Email" %} {% endelement %} {% endslot %} {% endelement %} {% if new_emailaddress %} {% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/email_confirm.html000066400000000000000000000032441467545753200253010ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load account %} {% load allauth %} {% block head_title %} {% trans "Confirm Email Address" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Confirm Email Address" %} {% endelement %} {% if confirmation %} {% user_display confirmation.email_address.user as user_display %} {% if can_confirm %} {% element p %} {% blocktrans with confirmation.email_address.email as email %}Please confirm that {{ email }} is an email address for user {{ user_display }}.{% endblocktrans %} {% endelement %} {% url 'account_confirm_email' confirmation.key as action_url %} {% element form method="post" action=action_url %} {% slot actions %} {% csrf_token %} {{ redirect_field }} {% element button type="submit" %} {% trans 'Confirm' %} {% endelement %} {% endslot %} {% endelement %} {% else %} {% element p %} {% blocktrans %}Unable to confirm {{ email }} because it is already confirmed by a different account.{% endblocktrans %} {% endelement %} {% endif %} {% else %} {% url 'account_email' as email_url %} {% element p %} {% blocktrans %}This email confirmation link expired or is invalid. Please issue a new email confirmation request.{% endblocktrans %} {% endelement %} {% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/login.html000066400000000000000000000044761467545753200236150ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth account %} {% block head_title %} {% trans "Sign In" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Sign In" %} {% endelement %} {% if not SOCIALACCOUNT_ONLY %} {% setvar link %} {% endsetvar %} {% setvar end_link %} {% endsetvar %} {% element p %} {% blocktranslate %}If you have not created an account yet, then please {{ link }}sign up{{ end_link }} first.{% endblocktranslate %} {% endelement %} {% url 'account_login' as login_url %} {% element form form=form method="post" action=login_url tags="entrance,login" %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" tags="prominent,login" %} {% trans "Sign In" %} {% endelement %} {% endslot %} {% endelement %} {% endif %} {% if LOGIN_BY_CODE_ENABLED or PASSKEY_LOGIN_ENABLED %} {% element hr %} {% endelement %} {% element button_group vertical=True %} {% if PASSKEY_LOGIN_ENABLED %} {% element button type="submit" form="mfa_login" id="passkey_login" tags="prominent,login,outline,primary" %} {% trans "Sign in with a passkey" %} {% endelement %} {% endif %} {% if LOGIN_BY_CODE_ENABLED %} {% element button href=request_login_code_url tags="prominent,login,outline,primary" %} {% trans "Mail me a sign-in code" %} {% endelement %} {% endif %} {% endelement %} {% endif %} {% if SOCIALACCOUNT_ENABLED %} {% include "socialaccount/snippets/login.html" with page_layout="entrance" %} {% endif %} {% endblock content %} {% block extra_body %} {{ block.super }} {% if PASSKEY_LOGIN_ENABLED %} {% include "mfa/webauthn/snippets/login_script.html" with button_id="passkey_login" %} {% endif %} {% endblock %} django-allauth-65.0.2/allauth/templates/account/logout.html000066400000000000000000000014031467545753200240010ustar00rootroot00000000000000{% extends "account/base_manage.html" %} {% load allauth i18n %} {% block head_title %} {% trans "Sign Out" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Sign Out" %} {% endelement %} {% element p %} {% trans 'Are you sure you want to sign out?' %} {% endelement %} {% url 'account_logout' as action_url %} {% element form method="post" action=action_url no_visible_fields=True %} {% slot body %} {% csrf_token %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" %} {% trans 'Sign Out' %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/messages/000077500000000000000000000000001467545753200234135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/account/messages/cannot_delete_primary_email.txt000066400000000000000000000001551467545753200316730ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}You cannot remove your primary email address ({{email}}).{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/email_confirmation_failed.txt000066400000000000000000000002071467545753200313160ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Unable to confirm {{email}} because it is already confirmed by a different account.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/email_confirmation_sent.txt000066400000000000000000000001311467545753200310370ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Confirmation email sent to {{email}}.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/email_confirmed.txt000066400000000000000000000001211467545753200272630ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}You have confirmed {{email}}.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/email_deleted.txt000066400000000000000000000001241467545753200267260ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Removed email address {{email}}.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/logged_in.txt000066400000000000000000000002121467545753200260760ustar00rootroot00000000000000{% load account %} {% load i18n %} {% user_display user as name %} {% blocktrans %}Successfully signed in as {{name}}.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/logged_out.txt000066400000000000000000000001101467545753200262740ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}You have signed out.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/login_code_sent.txt000066400000000000000000000001401467545753200273020ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}A sign-in code has been mailed to {{email}}.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/password_changed.txt000066400000000000000000000001221467545753200274620ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Password successfully changed.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/password_set.txt000066400000000000000000000001161467545753200266670ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Password successfully set.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/primary_email_set.txt000066400000000000000000000001161467545753200276570ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Primary email address set.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/messages/unverified_primary_email.txt000066400000000000000000000001401467545753200312210ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Your primary email address must be verified.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/account/password_change.html000066400000000000000000000015371467545753200256470ustar00rootroot00000000000000{% extends "account/base_manage_password.html" %} {% load allauth i18n %} {% block head_title %} {% trans "Change Password" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Change Password" %} {% endelement %} {% url 'account_change_password' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {{ redirect_field }} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" %} {% trans "Change Password" %} {% endelement %} {% trans "Forgot Password?" %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/password_reset.html000066400000000000000000000022301467545753200255330ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n allauth account %} {% block head_title %} {% trans "Password Reset" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Password Reset" %} {% endelement %} {% if user.is_authenticated %} {% include "account/snippets/already_logged_in.html" %} {% endif %} {% element p %} {% trans "Forgotten your password? Enter your email address below, and we'll send you an email allowing you to reset it." %} {% endelement %} {% url 'account_reset_password' as reset_url %} {% element form form=form method="post" action=reset_url %} {% slot body %} {% csrf_token %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" %} {% trans 'Reset My Password' %} {% endelement %} {% endslot %} {% endelement %} {% element p %} {% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/password_reset_done.html000066400000000000000000000012121467545753200265370ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth %} {% load account %} {% block head_title %} {% trans "Password Reset" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Password Reset" %} {% endelement %} {% if user.is_authenticated %} {% include "account/snippets/already_logged_in.html" %} {% endif %} {% element p %} {% blocktrans %}We have sent you an email. If you have not received it please check your spam folder. Otherwise contact us if you do not receive it in a few minutes.{% endblocktrans %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/password_reset_from_key.html000066400000000000000000000023451467545753200274350ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Change Password" %} {% endblock head_title %} {% block content %} {% element h1 %} {% if token_fail %} {% trans "Bad Token" %} {% else %} {% trans "Change Password" %} {% endif %} {% endelement %} {% if token_fail %} {% url 'account_reset_password' as passwd_reset_url %} {% element p %} {% blocktrans %}The password reset link was invalid, possibly because it has already been used. Please request a new password reset.{% endblocktrans %} {% endelement %} {% else %} {% element form method="post" action=action_url %} {% slot body %} {% csrf_token %} {{ redirect_field }} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" name="action" %} {% trans 'Change Password' %} {% endelement %} {% endslot %} {% endelement %} {% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/password_reset_from_key_done.html000066400000000000000000000005711467545753200304410ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Change Password" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Change Password" %} {% endelement %} {% element p %} {% trans 'Your password is now changed.' %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/password_set.html000066400000000000000000000014061467545753200252100ustar00rootroot00000000000000{% extends "account/base_manage_password.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Set Password" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Set Password" %} {% endelement %} {% url 'account_set_password' as action_url %} {% element form method="post" action=action_url %} {% slot body %} {% csrf_token %} {{ redirect_field }} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" name="action" %} {% trans 'Set Password' %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/reauthenticate.html000066400000000000000000000014061467545753200255000ustar00rootroot00000000000000{% extends "account/base_reauthenticate.html" %} {% load allauth %} {% load i18n %} {% block reauthenticate_content %} {% element p %} {% blocktranslate %}Enter your password:{% endblocktranslate %} {% endelement %} {% url 'account_reauthenticate' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" tags="primary,reauthenticate" %} {% trans "Confirm" %} {% endelement %} {% endslot %} {% endelement %} {% endblock %} django-allauth-65.0.2/allauth/templates/account/request_login_code.html000066400000000000000000000022451467545753200263470ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth account %} {% block head_title %} {% translate "Sign In" %} {% endblock head_title %} {% block content %} {% element h1 %} {% translate "Mail me a sign-in code" %} {% endelement %} {% element p %} {% blocktranslate %}You will receive an email containing a special code for a password-free sign-in.{% endblocktranslate %} {% endelement %} {% url 'account_request_login_code' as login_url %} {% element form form=form method="post" action=login_url tags="entrance,login" %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" tags="prominent,login" %} {% translate "Request Code" %} {% endelement %} {% endslot %} {% endelement %} {% url 'account_login' as login_url %} {% element button href=login_url tags="link" %} {% translate "Other sign-in options" %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/signup.html000066400000000000000000000031201467545753200237730ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load allauth i18n %} {% block head_title %} {% trans "Signup" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Sign Up" %} {% endelement %} {% setvar link %} {% endsetvar %} {% setvar end_link %} {% endsetvar %} {% element p %} {% blocktranslate %}Already have an account? Then please {{ link }}sign in{{ end_link }}.{% endblocktranslate %} {% endelement %} {% if not SOCIALACCOUNT_ONLY %} {% url 'account_signup' as action_url %} {% element form form=form method="post" action=action_url tags="entrance,signup" %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button tags="prominent,signup" type="submit" %} {% trans "Sign Up" %} {% endelement %} {% endslot %} {% endelement %} {% endif %} {% if PASSKEY_SIGNUP_ENABLED %} {% element hr %} {% endelement %} {% element button href=signup_by_passkey_url tags="prominent,signup,outline,primary" %} {% trans "Sign up using a passkey" %} {% endelement %} {% endif %} {% if SOCIALACCOUNT_ENABLED %} {% include "socialaccount/snippets/login.html" with page_layout="entrance" %} {% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/signup_by_passkey.html000066400000000000000000000024211467545753200262270ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load allauth i18n %} {% block head_title %} {% trans "Signup" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Passkey Sign Up" %} {% endelement %} {% setvar link %} {% endsetvar %} {% setvar end_link %} {% endsetvar %} {% element p %} {% blocktranslate %}Already have an account? Then please {{ link }}sign in{{ end_link }}.{% endblocktranslate %} {% endelement %} {% url 'account_signup_by_passkey' as action_url %} {% element form form=form method="post" action=action_url tags="entrance,signup" %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button tags="prominent,signup" type="submit" %} {% trans "Sign Up" %} {% endelement %} {% endslot %} {% endelement %} {% element hr %} {% endelement %} {% element button href=signup_url tags="prominent,signup,outline,primary" %} {% trans "Other options" %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/signup_closed.html000066400000000000000000000006141467545753200253310ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Sign Up Closed" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Sign Up Closed" %} {% endelement %} {% element p %} {% trans "We are sorry, but the sign up is currently closed." %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/snippets/000077500000000000000000000000001467545753200234515ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/account/snippets/already_logged_in.html000066400000000000000000000005221467545753200277660ustar00rootroot00000000000000{% load i18n %} {% load account %} {% load allauth %} {% user_display user as user_display %} {% element alert %} {% slot message %} {% blocktranslate %}Note{% endblocktranslate %}: {% blocktranslate %}You are already logged in as {{ user_display }}.{% endblocktranslate %} {% endslot %} {% endelement %} django-allauth-65.0.2/allauth/templates/account/snippets/warn_no_email.html000066400000000000000000000004121467545753200271460ustar00rootroot00000000000000{% load i18n allauth %} {% element p %} {% trans 'Warning:' %} {% trans "You currently do not have any email address set up. You should really add an email address so you can receive notifications, reset your password, etc." %} {% endelement %} django-allauth-65.0.2/allauth/templates/account/verification_sent.html000066400000000000000000000012261467545753200262060ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Verify Your Email Address" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Verify Your Email Address" %} {% endelement %} {% element p %} {% blocktrans %}We have sent an email to you for verification. Follow the link provided to finalize the signup process. If you do not see the verification email in your main inbox, check your spam folder. Please contact us if you do not receive the verification email within a few minutes.{% endblocktrans %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/account/verified_email_required.html000066400000000000000000000021041467545753200273330ustar00rootroot00000000000000{% extends "account/base_manage.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Verify Your Email Address" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Verify Your Email Address" %} {% endelement %} {% url 'account_email' as email_url %} {% element p %} {% blocktrans %}This part of the site requires us to verify that you are who you claim to be. For this purpose, we require that you verify ownership of your email address. {% endblocktrans %} {% endelement %} {% element p %} {% blocktrans %}We have sent an email to you for verification. Please click on the link inside that email. If you do not see the verification email in your main inbox, check your spam folder. Otherwise contact us if you do not receive it within a few minutes.{% endblocktrans %} {% endelement %} {% element p %} {% blocktrans %}Note: you can still change your email address.{% endblocktrans %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/allauth/000077500000000000000000000000001467545753200216025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/allauth/elements/000077500000000000000000000000001467545753200234165ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/allauth/elements/alert.html000066400000000000000000000001051467545753200254070ustar00rootroot00000000000000{% load allauth %}

{% slot message %} {% endslot %}

django-allauth-65.0.2/allauth/templates/allauth/elements/badge.html000066400000000000000000000002001467545753200253360ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/elements/button.html000066400000000000000000000010171467545753200256160ustar00rootroot00000000000000{% load allauth %} {% comment %} djlint:off {% endcomment %} <{% if attrs.href %}a href="{{ attrs.href }}"{% else %}button{% endif %} {% if attrs.form %}form="{{ attrs.form }}"{% endif %} {% if attrs.id %}id="{{ attrs.id }}"{% endif %} {% if attrs.name %}name="{{ attrs.name }}"{% endif %} {% if attrs.value %}value="{{ attrs.value }}"{% endif %} {% if attrs.type %}type="{{ attrs.type }}"{% endif %} {% if attrs.id %}id="{{ attrs.id }}"{% endif %} > {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/elements/button_group.html000066400000000000000000000001011467545753200270230ustar00rootroot00000000000000{% load allauth %}
{% slot %} {% endslot %}
django-allauth-65.0.2/allauth/templates/allauth/elements/field.html000066400000000000000000000037701467545753200253760ustar00rootroot00000000000000{% load allauth %} {{ attrs.errors }}

{% if attrs.type == "textarea" %} {% else %} {% if attrs.type != "checkbox" and attrs.type != "radio" %} {% endif %} {% if attrs.type == "checkbox" or attrs.type == "radio" %} {% endif %} {% endif %} {% if slots.help_text %} {% slot help_text %} {% endslot %} {% endif %}

django-allauth-65.0.2/allauth/templates/allauth/elements/fields.html000066400000000000000000000000261467545753200255500ustar00rootroot00000000000000{{ attrs.form.as_p }} django-allauth-65.0.2/allauth/templates/allauth/elements/form.html000066400000000000000000000002511467545753200252450ustar00rootroot00000000000000{% load allauth %}
{% slot body %} {% endslot %} {% slot actions %} {% endslot %}
django-allauth-65.0.2/allauth/templates/allauth/elements/h1.html000066400000000000000000000001341467545753200246120ustar00rootroot00000000000000{% comment %} djlint:off {% endcomment %}{% load allauth %}

{% slot %}{% endslot %}

django-allauth-65.0.2/allauth/templates/allauth/elements/h2.html000066400000000000000000000001341467545753200246130ustar00rootroot00000000000000{% comment %} djlint:off {% endcomment %}{% load allauth %}

{% slot %}{% endslot %}

django-allauth-65.0.2/allauth/templates/allauth/elements/hr.html000066400000000000000000000000051467545753200247100ustar00rootroot00000000000000
django-allauth-65.0.2/allauth/templates/allauth/elements/img.html000066400000000000000000000001241467545753200250550ustar00rootroot00000000000000 django-allauth-65.0.2/allauth/templates/allauth/elements/p.html000066400000000000000000000001321467545753200245370ustar00rootroot00000000000000{% comment %} djlint:off {% endcomment %}{% load allauth %}

{% slot %}{% endslot %}

django-allauth-65.0.2/allauth/templates/allauth/elements/panel.html000066400000000000000000000004451467545753200254060ustar00rootroot00000000000000{% load allauth %}

{% slot title %} {% endslot %}

{% slot body %} {% endslot %} {% if slots.actions %}
    {% for action in slots.actions %}
  • {{ action }}
  • {% endfor %}
{% endif %}
django-allauth-65.0.2/allauth/templates/allauth/elements/provider.html000066400000000000000000000001301467545753200261300ustar00rootroot00000000000000
  • {{ attrs.name }}
  • django-allauth-65.0.2/allauth/templates/allauth/elements/provider_list.html000066400000000000000000000000771467545753200271750ustar00rootroot00000000000000{% load allauth %}
      {% slot %} {% endslot %}
    django-allauth-65.0.2/allauth/templates/allauth/elements/table.html000066400000000000000000000001051467545753200253670ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %}
    django-allauth-65.0.2/allauth/templates/allauth/elements/tbody.html000066400000000000000000000001051467545753200254210ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/elements/td.html000066400000000000000000000001701467545753200247110ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/elements/th.html000066400000000000000000000000771467545753200247230ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/elements/thead.html000066400000000000000000000001051467545753200253650ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/elements/tr.html000066400000000000000000000000771467545753200247350ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %} django-allauth-65.0.2/allauth/templates/allauth/layouts/000077500000000000000000000000001467545753200233025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/allauth/layouts/base.html000066400000000000000000000071111467545753200251020ustar00rootroot00000000000000{% load i18n %} {% block head_title %} {% endblock head_title %} {% block extra_head %} {% endblock extra_head %} {% block body %} {% if messages %}
    {% trans "Messages:" %}
      {% for message in messages %}
    • {{ message }}
    • {% endfor %}
    {% endif %}
    {% trans "Menu:" %}
    {% block content %} {% endblock content %} {% endblock body %} {% block extra_body %} {% endblock extra_body %} django-allauth-65.0.2/allauth/templates/allauth/layouts/entrance.html000066400000000000000000000001141467545753200257630ustar00rootroot00000000000000{% extends "allauth/layouts/base.html" %} {% block content %}{% endblock %} django-allauth-65.0.2/allauth/templates/allauth/layouts/manage.html000066400000000000000000000001141467545753200254140ustar00rootroot00000000000000{% extends "allauth/layouts/base.html" %} {% block content %}{% endblock %} django-allauth-65.0.2/allauth/templates/mfa/000077500000000000000000000000001467545753200207135ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/authenticate.html000066400000000000000000000056111467545753200242620ustar00rootroot00000000000000{% extends "mfa/base_entrance.html" %} {% load i18n %} {% load allauth %} {% load allauth static %} {% block head_title %} {% trans "Sign In" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Two-Factor Authentication" %} {% endelement %} {% element p %} {% blocktranslate %}Your account is protected by two-factor authentication. Please enter an authenticator code:{% endblocktranslate %} {% endelement %} {% url 'mfa_authenticate' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" tags="primary,mfa,login" %} {% trans "Sign In" %} {% endelement %} {% if "webauthn" not in MFA_SUPPORTED_TYPES %} {% element button type="submit" form="logout-from-stage" tags="link,mfa,cancel" %} {% trans "Cancel" %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% if "webauthn" in MFA_SUPPORTED_TYPES %} {% element hr %} {% endelement %} {% element h2 %} {% translate "Alternative options" %} {% endelement %} {% element button_group vertical=True %} {% element button form="webauthn_form" id="mfa_webauthn_authenticate" type="button" tags="outline,primary" %} {% trans "Use a security key" %} {% endelement %} {% element button type="submit" form="logout-from-stage" tags="outline,primary,mfa,cancel" %} {% trans "Cancel" %} {% endelement %} {% endelement %} {% if "webauthn" in MFA_SUPPORTED_TYPES %} {% element form id="webauthn_form" form=webauthn_form method="post" action=action_url no_visible_fields=True %} {% slot body %} {% csrf_token %} {% element fields form=webauthn_form %} {% endelement %} {% endslot %} {% endelement %} {{ js_data|json_script:"js_data" }} {% include "mfa/webauthn/snippets/scripts.html" %} {% endif %} {% endif %}
    {% csrf_token %}
    {% endblock content %} django-allauth-65.0.2/allauth/templates/mfa/base_entrance.html000066400000000000000000000000561467545753200243730ustar00rootroot00000000000000{% extends "allauth/layouts/entrance.html" %} django-allauth-65.0.2/allauth/templates/mfa/base_manage.html000066400000000000000000000000541467545753200240220ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} django-allauth-65.0.2/allauth/templates/mfa/email/000077500000000000000000000000001467545753200220025ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/email/recovery_codes_generated_message.txt000066400000000000000000000003651467545753200313040ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}A new set of Two-Factor Authentication recovery codes has been generated.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/mfa/email/recovery_codes_generated_subject.txt000066400000000000000000000001711467545753200313120ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}New Recovery Codes Generated{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/mfa/email/totp_activated_message.txt000066400000000000000000000003101467545753200272530ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Authenticator app activated.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/mfa/email/totp_activated_subject.txt000066400000000000000000000001701467545753200272720ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Authenticator App Activated{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/mfa/email/totp_deactivated_message.txt000066400000000000000000000003121467545753200275660ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}Authenticator app deactivated.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/mfa/email/totp_deactivated_subject.txt000066400000000000000000000001721467545753200276050ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Authenticator App Deactivated{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/mfa/email/webauthn_added_message.txt000066400000000000000000000003161467545753200272050ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}A new security key has been added.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/mfa/email/webauthn_added_subject.txt000066400000000000000000000001571467545753200272230ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Security Key Added{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/mfa/email/webauthn_removed_message.txt000066400000000000000000000003141467545753200276030ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}A security key has been removed.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/mfa/email/webauthn_removed_subject.txt000066400000000000000000000001611467545753200276160ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Security Key Removed{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/mfa/index.html000066400000000000000000000125411467545753200227130ustar00rootroot00000000000000{% extends "mfa/base_manage.html" %} {% load allauth %} {% load i18n %} {% block head_title %} {% trans "Two-Factor Authentication" %} {% endblock head_title %} {% block content %} {% element h1 tags="mfa,index" %} {% trans "Two-Factor Authentication" %} {% endelement %} {% if "totp" in MFA_SUPPORTED_TYPES %} {% element panel %} {% slot title %} {% translate "Authenticator App" %} {% endslot %} {% slot body %} {% if authenticators.totp %} {% element p %} {% translate "Authentication using an authenticator app is active." %} {% endelement %} {% else %} {% element p %} {% translate "An authenticator app is not active." %} {% endelement %} {% endif %} {% endslot %} {% slot actions %} {% url 'mfa_deactivate_totp' as deactivate_url %} {% url 'mfa_activate_totp' as activate_url %} {% if authenticators.totp %} {% element button href=deactivate_url tags="danger,delete,panel" %} {% translate "Deactivate" %} {% endelement %} {% else %} {% element button href=activate_url tags="panel" %} {% translate "Activate" %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% endif %} {% if "webauthn" in MFA_SUPPORTED_TYPES %} {% element panel %} {% slot title %} {% translate "Security Keys" %} {% endslot %} {% slot body %} {% if authenticators.webauthn|length %} {% element p %} {% blocktranslate count count=authenticators.webauthn|length %}You have added {{ count }} security key.{% plural %}You have added {{ count }} security keys.{% endblocktranslate %} {% endelement %} {% else %} {% element p %} {% translate "No security keys have been added." %} {% endelement %} {% endif %} {% endslot %} {% slot actions %} {% if authenticators.webauthn|length %} {% url 'mfa_list_webauthn' as webauthn_list_url %} {% element button href=webauthn_list_url %} {% translate "Manage" %} {% endelement %} {% else %} {% url 'mfa_add_webauthn' as webauthn_add_url %} {% element button href=webauthn_add_url %} {% translate "Add" %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% endif %} {% if "recovery_codes" in MFA_SUPPORTED_TYPES %} {% with total_count=authenticators.recovery_codes.generate_codes|length unused_count=authenticators.recovery_codes.get_unused_codes|length %} {% element panel %} {% slot title %} {% translate "Recovery Codes" %} {% endslot %} {% slot body %} {% if authenticators.recovery_codes %} {% element p %} {% blocktranslate count unused_count=unused_count %}There is {{ unused_count }} out of {{ total_count }} recovery codes available.{% plural %}There are {{ unused_count }} out of {{ total_count }} recovery codes available.{% endblocktranslate %} {% endelement %} {% else %} {% element p %} {% translate "No recovery codes set up." %} {% endelement %} {% endif %} {% endslot %} {% if is_mfa_enabled %} {% if authenticators.recovery_codes %} {% if unused_count > 0 %} {% slot actions %} {% url 'mfa_view_recovery_codes' as view_url %} {% element button href=view_url tags="panel" %} {% translate "View" %} {% endelement %} {% endslot %} {% slot actions %} {% url 'mfa_download_recovery_codes' as download_url %} {% element button href=download_url tags="secondary,panel" %} {% translate "Download" %} {% endelement %} {% endslot %} {% endif %} {% endif %} {% slot actions %} {% url 'mfa_generate_recovery_codes' as generate_url %} {% element button href=generate_url tags="secondary,panel" %} {% translate "Generate" %} {% endelement %} {% endslot %} {% endif %} {% endelement %} {% endwith %} {% endif %} {% endblock content %} django-allauth-65.0.2/allauth/templates/mfa/messages/000077500000000000000000000000001467545753200225225ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/messages/recovery_codes_generated.txt000066400000000000000000000001431467545753200303120ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}A new set of recovery codes has been generated.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/mfa/messages/totp_activated.txt000066400000000000000000000001201467545753200262660ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Authenticator app activated.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/mfa/messages/totp_deactivated.txt000066400000000000000000000001221467545753200266010ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Authenticator app deactivated.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/mfa/messages/webauthn_added.txt000066400000000000000000000001071467545753200262170ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Security key added.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/mfa/messages/webauthn_removed.txt000066400000000000000000000001111467545753200266120ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}Security key removed.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/mfa/reauthenticate.html000066400000000000000000000014051467545753200246060ustar00rootroot00000000000000{% extends "account/base_reauthenticate.html" %} {% load i18n %} {% load allauth %} {% block reauthenticate_content %} {% element p %} {% blocktranslate %}Enter an authenticator code:{% endblocktranslate %} {% endelement %} {% url 'mfa_reauthenticate' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" tags="primary,mfa,login" %} {% trans "Confirm" %} {% endelement %} {% endslot %} {% endelement %} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/recovery_codes/000077500000000000000000000000001467545753200237265ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/recovery_codes/base.html000066400000000000000000000002071467545753200255250ustar00rootroot00000000000000{% extends "mfa/base_manage.html" %} {% load i18n %} {% block head_title %} {% trans "Recovery Codes" %} {% endblock head_title %} django-allauth-65.0.2/allauth/templates/mfa/recovery_codes/download.txt000066400000000000000000000000661467545753200263000ustar00rootroot00000000000000{% for code in unused_codes %}{{ code }} {% endfor %} django-allauth-65.0.2/allauth/templates/mfa/recovery_codes/generate.html000066400000000000000000000022731467545753200264120ustar00rootroot00000000000000{% extends "mfa/recovery_codes/base.html" %} {% load i18n %} {% load allauth %} {% block content %} {% element h1 %} {% translate "Recovery Codes" %} {% endelement %} {% element p %} {% blocktranslate %}You are about to generate a new set of recovery codes for your account.{% endblocktranslate %} {% if unused_code_count %} {% blocktranslate %}This action will invalidate your existing codes.{% endblocktranslate %} {% endif %} {% blocktranslate %}Are you sure?{% endblocktranslate %} {% endelement %} {% url 'mfa_generate_recovery_codes' as action_url %} {% element form method="post" action=action_url no_visible_fields=True %} {% slot body %} {% csrf_token %} {{ form.as_p }} {% endslot %} {% slot actions %} {% setvar tags %} {% if unused_code_count %} danger {% else %} {% endif %} {% endsetvar %} {% element button type="submit" tags=tags %} {% trans "Generate" %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/mfa/recovery_codes/index.html000066400000000000000000000023651467545753200257310ustar00rootroot00000000000000{% extends "mfa/recovery_codes/base.html" %} {% load i18n %} {% load allauth %} {% block content %} {% element h1 %} {% translate "Recovery Codes" %} {% endelement %} {% element p %} {% blocktranslate count unused_count=unused_codes|length %}There is {{ unused_count }} out of {{ total_count }} recovery codes available.{% plural %}There are {{ unused_count }} out of {{ total_count }} recovery codes available.{% endblocktranslate %} {% endelement %} {% element field id="recovery_codes" type="textarea" disabled=True rows=unused_codes|length readonly=True %} {% slot label %} {% translate "Unused codes" %} {% endslot %} {% comment %} djlint:off {% endcomment %} {% slot value %}{% for code in unused_codes %}{% if forloop.counter0 %} {% endif %}{{ code }}{% endfor %}{% endslot %} {% comment %} djlint:on {% endcomment %} {% endelement %} {% if unused_codes %} {% url 'mfa_download_recovery_codes' as download_url %} {% element button href=download_url %} {% translate "Download codes" %} {% endelement %} {% endif %} {% url 'mfa_generate_recovery_codes' as generate_url %} {% element button href=generate_url %} {% translate "Generate new codes" %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/mfa/totp/000077500000000000000000000000001467545753200217015ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/totp/activate_form.html000066400000000000000000000030361467545753200254140ustar00rootroot00000000000000{% extends "mfa/totp/base.html" %} {% load allauth i18n %} {% block head_title %} {% translate "Activate Authenticator App" %} {% endblock head_title %} {% block content %} {% element h1 %} {% translate "Activate Authenticator App" %} {% endelement %} {% element p %} {% blocktranslate %}To protect your account with two-factor authentication, scan the QR code below with your authenticator app. Then, input the verification code generated by the app below.{% endblocktranslate %} {% endelement %} {% url 'mfa_activate_totp' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% element img src=totp_svg_data_uri alt=form.secret tags="mfa,totp,qr" %} {% endelement %} {% csrf_token %} {% element field id="authenticator_secret" type="text" value=form.secret disabled=True %} {% slot label %} {% translate "Authenticator secret" %} {% endslot %} {% slot help_text %} {% translate "You can store this secret and use it to reinstall your authenticator app at a later time." %} {% endslot %} {% endelement %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" %} {% trans "Activate" %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/mfa/totp/base.html000066400000000000000000000002121467545753200234740ustar00rootroot00000000000000{% extends "mfa/base_manage.html" %} {% load i18n %} {% block head_title %} {% trans "Authenticator App" %} {% endblock head_title %} django-allauth-65.0.2/allauth/templates/mfa/totp/deactivate_form.html000066400000000000000000000017511467545753200257270ustar00rootroot00000000000000{% extends "mfa/totp/base.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Deactivate Authenticator App" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Deactivate Authenticator App" %} {% endelement %} {% element p %} {% blocktranslate %}You are about to deactivate authenticator app based authentication. Are you sure?{% endblocktranslate %} {% endelement %} {% url 'mfa_deactivate_totp' as action_url %} {% element form form=form method="post" action=action_url no_visible_fields=True %} {% slot body %} {% csrf_token %} {% element fields form=form %} {{ form.as_p }} {% endelement %} {% endslot %} {% slot actions %} {% element button tags="danger,delete" type="submit" %} {% trans "Deactivate" %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/000077500000000000000000000000001467545753200225305ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/webauthn/add_form.html000066400000000000000000000021401467545753200251660ustar00rootroot00000000000000{% extends "mfa/webauthn/base.html" %} {% load i18n %} {% load static %} {% load allauth %} {% block content %} {% element h1 %} {% trans "Add Security Key" %} {% endelement %} {% url 'mfa_add_webauthn' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button id="mfa_webauthn_add" type="button" %} {% trans "Add" %} {% endelement %} {% endslot %} {% endelement %} {% include "mfa/webauthn/snippets/scripts.html" %} {{ js_data|json_script:"js_data" }} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/authenticator_confirm_delete.html000066400000000000000000000013121467545753200313240ustar00rootroot00000000000000{% extends "mfa/webauthn/base.html" %} {% load i18n %} {% load allauth %} {% block content %} {% element h1 %} {% trans "Remove Security Key" %} {% endelement %} {% element p %} {% blocktranslate %}Are you sure you want to remove this security key?{% endblocktranslate %} {% endelement %} {% url 'mfa_remove_webauthn' pk=authenticator.pk as action_url %} {% element form method="post" action=action_url no_visible_fields=True %} {% slot actions %} {% csrf_token %} {% element button tags="danger" type="submit" %} {% translate "Remove" %} {% endelement %} {% endslot %} {% endelement %} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/authenticator_list.html000066400000000000000000000066261467545753200273350ustar00rootroot00000000000000{% extends "mfa/webauthn/base.html" %} {% load i18n %} {% load static %} {% load allauth %} {% load humanize %} {% block content %} {% element h1 %} {% trans "Security Keys" %} {% endelement %} {% if authenticators|length == 0 %} {% element p %} {% blocktranslate %}No security keys have been added.{% endblocktranslate %} {% endelement %} {% else %} {% element table %} {% element thead %} {% element th %} {% translate "Key" %} {% endelement %} {% element th %} {% translate "Usage" %} {% endelement %} {% element th %} {% endelement %} {% endelement %} {% element tbody %} {% for authenticator in authenticators %} {% element tr %} {% element td %} {{ authenticator }} {% if authenticator.wrap.is_passwordless is True %} {% element badge tags="mfa,key,primary" %} {% translate "Passkey" %} {% endelement %} {% elif authenticator.wrap.is_passwordless is False %} {% element badge tags="mfa,key,secondary" %} {% translate "Security key" %} {% endelement %} {% else %} {% element badge title=_("This key does not indicate whether it is a passkey.") tags="mfa,key,warning" %} {% translate "Unspecified" %} {% endelement %} {% endif %} {% endelement %} {% element td %} {% blocktranslate with created_at=authenticator.created_at|date:"SHORT_DATE_FORMAT" %}Added on {{ created_at }}{% endblocktranslate %}. {% if authenticator.last_used_at %} {% blocktranslate with last_used=authenticator.last_used_at|naturaltime %}Last used {{ last_used }}{% endblocktranslate %} {% else %} Not used. {% endif %} {% endelement %} {% element td align="right" %} {% url 'mfa_edit_webauthn' pk=authenticator.pk as edit_url %} {% element button tags="mfa,authenticator,edit,tool" href=edit_url %} {% translate "Edit" %} {% endelement %} {% url 'mfa_remove_webauthn' pk=authenticator.pk as remove_url %} {% element button tags="mfa,authenticator,danger,delete,tool" href=remove_url %} {% translate "Remove" %} {% endelement %} {% endelement %} {% endelement %} {% endfor %} {% endelement %} {% endelement %} {% endif %} {% url 'mfa_add_webauthn' as add_url %} {% element button href=add_url %} {% translate "Add" %} {% endelement %} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/base.html000066400000000000000000000002061467545753200243260ustar00rootroot00000000000000{% extends "mfa/base_manage.html" %} {% load i18n %} {% block head_title %} {% trans "Security Keys" %} {% endblock head_title %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/edit_form.html000066400000000000000000000012411467545753200253640ustar00rootroot00000000000000{% extends "mfa/webauthn/base.html" %} {% load i18n %} {% load static %} {% load allauth %} {% block content %} {% element h1 %} {% trans "Edit Security Key" %} {% endelement %} {% url 'mfa_edit_webauthn' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button id="mfa_webauthn_edit" type="submit" %} {% trans "Save" %} {% endelement %} {% endslot %} {% endelement %} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/reauthenticate.html000066400000000000000000000021041467545753200264200ustar00rootroot00000000000000{% extends "account/base_reauthenticate.html" %} {% load i18n %} {% load allauth %} {% block reauthenticate_content %} {% url 'mfa_reauthenticate_webauthn' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button id="mfa_webauthn_reauthenticate" type="submit" tags="primary,mfa,login" %} {% trans "Use a security key" %} {% endelement %} {% endslot %} {% endelement %} {{ js_data|json_script:"js_data" }} {% include "mfa/webauthn/snippets/scripts.html" %} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/signup_form.html000066400000000000000000000032051467545753200257460ustar00rootroot00000000000000{% extends "account/base_entrance.html" %} {% load i18n %} {% load static %} {% load allauth %} {% block content %} {% element h1 %} {% trans "Create Passkey" %} {% endelement %} {% element p %} {% blocktranslate %}You are about to create a passkey for your account. As you can add additional keys later on, you can use a descriptive name to tell the keys apart.{% endblocktranslate %} {% endelement %} {% url 'mfa_signup_webauthn' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form %} {% endelement %} {% endslot %} {% slot actions %} {% element button id="mfa_webauthn_signup" type="button" %} {% trans "Create" %} {% endelement %} {% endslot %} {% endelement %} {% element button type="submit" form="logout-from-stage" tags="link,cancel" %} {% translate "Cancel" %} {% endelement %}
    {% csrf_token %}
    {% include "mfa/webauthn/snippets/scripts.html" %} {{ js_data|json_script:"js_data" }} {% endblock %} django-allauth-65.0.2/allauth/templates/mfa/webauthn/snippets/000077500000000000000000000000001467545753200243755ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/mfa/webauthn/snippets/login_script.html000066400000000000000000000006351467545753200277630ustar00rootroot00000000000000{% include "mfa/webauthn/snippets/scripts.html" %}
    {% csrf_token %} {{ redirect_field }}
    django-allauth-65.0.2/allauth/templates/mfa/webauthn/snippets/scripts.html000066400000000000000000000003401467545753200267470ustar00rootroot00000000000000{% load i18n static %} django-allauth-65.0.2/allauth/templates/openid/000077500000000000000000000000001467545753200214265ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/openid/base.html000066400000000000000000000000611467545753200232230ustar00rootroot00000000000000{% extends "socialaccount/base_entrance.html" %} django-allauth-65.0.2/allauth/templates/openid/login.html000066400000000000000000000013241467545753200234240ustar00rootroot00000000000000{% extends "openid/base.html" %} {% load i18n %} {% load allauth %} {% block head_title %} OpenID {% translate "Sign In" %} {% endblock head_title %} {% block content %} {% element h1 %} OpenID {% trans 'Sign In' %} {% endelement %} {% url 'openid_login' as action_url %} {% element form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {% endslot %} {% slot actions %} {% element button type="submit" %} {% translate "Sign In" %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/socialaccount/000077500000000000000000000000001467545753200227775ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/socialaccount/authentication_error.html000066400000000000000000000006771467545753200301270ustar00rootroot00000000000000{% extends "socialaccount/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Third-Party Login Failure" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Third-Party Login Failure" %} {% endelement %} {% element p %} {% trans "An error occurred while attempting to login via your third-party account." %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/socialaccount/base_entrance.html000066400000000000000000000000561467545753200264570ustar00rootroot00000000000000{% extends "allauth/layouts/entrance.html" %} django-allauth-65.0.2/allauth/templates/socialaccount/base_manage.html000066400000000000000000000000541467545753200261060ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} django-allauth-65.0.2/allauth/templates/socialaccount/connections.html000066400000000000000000000044161467545753200262140ustar00rootroot00000000000000{% extends "socialaccount/base_manage.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Account Connections" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Account Connections" %} {% endelement %} {% if form.accounts %} {% element p %} {% blocktrans %}You can sign in to your account using any of the following third-party accounts:{% endblocktrans %} {% endelement %} {% url 'socialaccount_connections' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% for acc in form.fields.account.choices %} {% with account=acc.0.instance.get_provider_account %} {% setvar radio_id %} id_account_{{ account.account.pk }} {% endsetvar %} {% setvar tags %} socialaccount,{{ account.account.provider }} {% endsetvar %} {% element field id=radio_id type="radio" name="account" value=account.account.pk %} {% slot label %} {{ account }} {% element badge tags=tags %} {{ account.get_brand.name }} {% endelement %} {% endslot %} {% endelement %} {% endwith %} {% endfor %} {% endslot %} {% slot actions %} {% element button tags="delete,danger" type="submit" %} {% trans 'Remove' %} {% endelement %} {% endslot %} {% endelement %} {% else %} {% element p %} {% trans 'You currently have no third-party accounts connected to this account.' %} {% endelement %} {% endif %} {% element h2 %} {% trans 'Add a Third-Party Account' %} {% endelement %} {% include "socialaccount/snippets/provider_list.html" with process="connect" %} {% include "socialaccount/snippets/login_extra.html" %} {% endblock content %} django-allauth-65.0.2/allauth/templates/socialaccount/email/000077500000000000000000000000001467545753200240665ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/socialaccount/email/account_connected_message.txt000066400000000000000000000003711467545753200320120ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}A third-party account from {{ provider }} has been connected to your account.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/socialaccount/email/account_connected_subject.txt000066400000000000000000000001721467545753200320240ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Third-Party Account Connected{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/socialaccount/email/account_disconnected_message.txt000066400000000000000000000003761467545753200325170ustar00rootroot00000000000000{% extends "account/email/base_notification.txt" %} {% load i18n %} {% block notification_message %}{% blocktrans %}A third-party account from {{ provider }} has been disconnected from your account.{% endblocktrans %}{% endblock notification_message %} django-allauth-65.0.2/allauth/templates/socialaccount/email/account_disconnected_subject.txt000066400000000000000000000001751467545753200325270ustar00rootroot00000000000000{% load i18n %} {% autoescape off %} {% blocktrans %}Third-Party Account Disconnected{% endblocktrans %} {% endautoescape %} django-allauth-65.0.2/allauth/templates/socialaccount/login.html000066400000000000000000000023371467545753200250020ustar00rootroot00000000000000{% extends "socialaccount/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Sign In" %} {% endblock head_title %} {% block content %} {% if process == "connect" %} {% element h1 %} {% blocktrans with provider.name as provider %}Connect {{ provider }}{% endblocktrans %} {% endelement %} {% element p %} {% blocktrans with provider.name as provider %}You are about to connect a new third-party account from {{ provider }}.{% endblocktrans %} {% endelement %} {% else %} {% element h1 %} {% blocktrans with provider.name as provider %}Sign In Via {{ provider }}{% endblocktrans %} {% endelement %} {% element p %} {% blocktrans with provider.name as provider %}You are about to sign in using a third-party account from {{ provider }}.{% endblocktrans %} {% endelement %} {% endif %} {% element form method="post" no_visible_fields=True %} {% slot actions %} {% csrf_token %} {% element button type="submit" %} {% trans "Continue" %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/socialaccount/login_cancelled.html000066400000000000000000000011011467545753200267600ustar00rootroot00000000000000{% extends "socialaccount/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Login Cancelled" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Login Cancelled" %} {% endelement %} {% url 'account_login' as login_url %} {% element p %} {% blocktrans %}You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to sign in.{% endblocktrans %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/socialaccount/login_redirect.html000066400000000000000000000005551467545753200266630ustar00rootroot00000000000000 {% load i18n allauth %} {% translate "Sign In" %} | {{ provider }} {% element p %} {% translate "Continue" %} {% endelement %} django-allauth-65.0.2/allauth/templates/socialaccount/messages/000077500000000000000000000000001467545753200246065ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/socialaccount/messages/account_connected.txt000066400000000000000000000001371467545753200310260ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}The third-party account has been connected.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/socialaccount/messages/account_connected_other.txt000066400000000000000000000001701467545753200322240ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}The third-party account is already connected to a different account.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/socialaccount/messages/account_connected_updated.txt000066400000000000000000000000751467545753200325350ustar00rootroot00000000000000{% extends "socialaccount/messages/account_connected.txt" %} django-allauth-65.0.2/allauth/templates/socialaccount/messages/account_disconnected.txt000066400000000000000000000001421467545753200315220ustar00rootroot00000000000000{% load i18n %} {% blocktrans %}The third-party account has been disconnected.{% endblocktrans %} django-allauth-65.0.2/allauth/templates/socialaccount/signup.html000066400000000000000000000020311467545753200251660ustar00rootroot00000000000000{% extends "socialaccount/base_entrance.html" %} {% load i18n %} {% load allauth %} {% block head_title %} {% trans "Signup" %} {% endblock head_title %} {% block content %} {% element h1 %} {% trans "Sign Up" %} {% endelement %} {% element p %} {% blocktrans with provider_name=account.get_provider.name site_name=site.name %}You are about to use your {{provider_name}} account to login to {{site_name}}. As a final step, please complete the following form:{% endblocktrans %} {% endelement %} {% url 'socialaccount_signup' as action_url %} {% element form form=form method="post" action=action_url %} {% slot body %} {% csrf_token %} {% element fields form=form unlabeled=True %} {% endelement %} {{ redirect_field }} {% endslot %} {% slot actions %} {% element button type="submit" %} {% trans "Sign Up" %} {% endelement %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templates/socialaccount/snippets/000077500000000000000000000000001467545753200246445ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/socialaccount/snippets/login.html000066400000000000000000000007621467545753200266470ustar00rootroot00000000000000{% load i18n %} {% load allauth %} {% load socialaccount %} {% get_providers as socialaccount_providers %} {% if socialaccount_providers %} {% if not SOCIALACCOUNT_ONLY %} {% element hr %} {% endelement %} {% element h2 %} {% translate "Or use a third-party" %} {% endelement %} {% endif %} {% include "socialaccount/snippets/provider_list.html" with process="login" %} {% include "socialaccount/snippets/login_extra.html" %} {% endif %} django-allauth-65.0.2/allauth/templates/socialaccount/snippets/login_extra.html000066400000000000000000000000621467545753200300430ustar00rootroot00000000000000{% load socialaccount %} {% providers_media_js %} django-allauth-65.0.2/allauth/templates/socialaccount/snippets/provider_list.html000066400000000000000000000015351467545753200304230ustar00rootroot00000000000000{% load allauth socialaccount %} {% get_providers as socialaccount_providers %} {% if socialaccount_providers %} {% element provider_list %} {% for provider in socialaccount_providers %} {% if provider.id == "openid" %} {% for brand in provider.get_brands %} {% provider_login_url provider openid=brand.openid_url process=process as href %} {% element provider name=brand.name provider_id=provider.id href=href %} {% endelement %} {% endfor %} {% endif %} {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %} {% element provider name=provider.name provider_id=provider.id href=href %} {% endelement %} {% endfor %} {% endelement %} {% endif %} django-allauth-65.0.2/allauth/templates/tests/000077500000000000000000000000001467545753200213125ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/tests/test_403_csrf.html000066400000000000000000000001541467545753200245620ustar00rootroot00000000000000{% load socialaccount %} Sign In django-allauth-65.0.2/allauth/templates/usersessions/000077500000000000000000000000001467545753200227155ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/usersessions/base_manage.html000066400000000000000000000000541467545753200260240ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} django-allauth-65.0.2/allauth/templates/usersessions/messages/000077500000000000000000000000001467545753200245245ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templates/usersessions/messages/sessions_logged_out.txt000066400000000000000000000001351467545753200313420ustar00rootroot00000000000000{% load i18n %} {% blocktranslate %}Signed out of all other sessions.{% endblocktranslate %} django-allauth-65.0.2/allauth/templates/usersessions/usersession_list.html000066400000000000000000000053501467545753200272230ustar00rootroot00000000000000{% extends "usersessions/base_manage.html" %} {% load allauth %} {% load i18n %} {% load humanize %} {% block head_title %} {% trans "Sessions" %} {% endblock head_title %} {% block content %} {% element h1 tags="usersessions,list" %} {% trans "Sessions" %} {% endelement %} {% if session_count > 1 %} {% url 'usersessions_list' as action_url %} {% else %} {% url 'account_logout' as action_url %} {% endif %} {% element form action=action_url method="post" tags="sessions" no_visible_fields=True %} {% slot body %} {% csrf_token %} {% element table tags="sessions" %} {% translate "Started At" %} {% translate "IP Address" %} {% translate "Browser" %} {% if show_last_seen_at %} {% translate "Last seen at" %} {% endif %} {% for session in sessions %} {{ session.created_at|naturaltime }} {{ session.ip }} {{ session.user_agent }} {% if show_last_seen_at %} {{ session.last_seen_at|naturaltime }} {% endif %} {% if session.is_current %} {% element badge tags="session,current" %} {% translate "Current" %} {% endelement %} {% else %} {% endif %} {% endfor %} {% endelement %} {% endslot %} {% slot actions %} {% if session_count > 1 %} {% element button type="submit" %} {% translate "Sign Out Other Sessions" %} {% endelement %} {% else %} {% element button type="submit" %} {% translate "Sign Out" %} {% endelement %} {% endif %} {% endslot %} {% endelement %} {% endblock content %} django-allauth-65.0.2/allauth/templatetags/000077500000000000000000000000001467545753200206445ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templatetags/__init__.py000066400000000000000000000000001467545753200227430ustar00rootroot00000000000000django-allauth-65.0.2/allauth/templatetags/allauth.py000066400000000000000000000114251467545753200226530ustar00rootroot00000000000000from django import template from django.template.base import FilterExpression, kwarg_re from django.template.loader import render_to_string from django.template.loader_tags import ExtendsNode from django.utils.safestring import mark_safe SLOTS_CONTEXT_KEY = "slots_context" LAYOUT_CONTEXT_KEY = "layout_context" def parse_tag(token, parser): bits = token.split_contents() tag_name = bits.pop(0) args = [] kwargs = {} for bit in bits: # Is this a kwarg or an arg? match = kwarg_re.match(bit) kwarg_format = match and match.group(1) if kwarg_format: key, value = match.groups() kwargs[key] = FilterExpression(value, parser) else: args.append(FilterExpression(bit, parser)) return (tag_name, args, kwargs) register = template.Library() @register.tag(name="slot") def do_slot(parser, token): nodelist = parser.parse(("endslot",)) bits = token.split_contents() bits.pop(0) slot_name = bits.pop(0) if bits else "default" parser.delete_first_token() return SlotNode(slot_name, nodelist) class SlotNode(template.Node): def __init__(self, name, nodelist): self.name = name self.nodelist = nodelist def render(self, context): slots = context.render_context.get(SLOTS_CONTEXT_KEY) with context.push(): if slots is None: if self.name in context["slots"]: return "".join(context["slots"][self.name]) return self.nodelist.render(context) else: result = self.nodelist.render(context) slot_list = slots.setdefault(self.name, []) slot_list.append(result) return "" @register.tag(name="element") def do_element(parser, token): nodelist = parser.parse(("endelement",)) tag_name, args, kwargs = parse_tag(token, parser) usage = f'{{% {tag_name} "element" argument=value %}} ... {{% end{tag_name} %}}' if len(args) > 1: raise template.TemplateSyntaxError("Usage: %s" % usage) parser.delete_first_token() return ElementNode(nodelist, args[0], kwargs) class ElementNode(template.Node): def __init__(self, nodelist, element, kwargs): self.element = element self.kwargs = kwargs self.nodelist = nodelist def render(self, context): from allauth.account.app_settings import TEMPLATE_EXTENSION slots = {} extends_context = context.render_context.get(ExtendsNode.context_key) layout = None if extends_context: # Extract layout from the {% extends %} tags for ec in extends_context: prefix = "allauth/layouts/" if ec.template_name.startswith(prefix): layout = ec.template_name[len(prefix) :].replace(".html", "") break if not layout: # In case we're in a {% element %} element, the extends context is # not there. layout = context.render_context.get(LAYOUT_CONTEXT_KEY) if not layout: # Or, similarly, for {% include %} we also lose the extends context. layout = context.get("page_layout") template_names = [] if layout: template_names.append(f"allauth/elements/{self.element}__{layout}.html") template_names.append(f"allauth/elements/{self.element}.html") with context.render_context.push( **{SLOTS_CONTEXT_KEY: slots, LAYOUT_CONTEXT_KEY: layout} ): slots["default"] = [self.nodelist.render(context)] attrs = {} for k, v in self.kwargs.items(): attrs[k] = v.resolve(context) tags = attrs.get("tags") if tags: attrs["tags"] = [tag.strip() for tag in tags.split(",")] return render_to_string( template_names, { "attrs": attrs, "slots": slots, "origin": self.origin.template_name.replace( f".{TEMPLATE_EXTENSION}", "" ), }, ) @register.tag(name="setvar") def do_setvar(parser, token): nodelist = parser.parse(("endsetvar",)) bits = token.split_contents() if len(bits) != 2: tag_name = bits[0] usage = f'{{% {tag_name} "setvar" var %}} ... {{% end{tag_name} %}}' raise template.TemplateSyntaxError("Usage: %s" % usage) parser.delete_first_token() return SetVarNode(nodelist, bits[1]) class SetVarNode(template.Node): def __init__(self, nodelist, var): self.nodelist = nodelist self.var = var def render(self, context): context[self.var] = mark_safe(self.nodelist.render(context).strip()) return "" django-allauth-65.0.2/allauth/tests.py000066400000000000000000000167321467545753200176770ustar00rootroot00000000000000import json import requests from datetime import date, datetime from unittest.mock import Mock from django.core.files.base import ContentFile from django.db import models from django.test import RequestFactory, TestCase from django.utils.http import base36_to_int, int_to_base36 from django.views import csrf from allauth import app_settings, utils class MockedResponse: def __init__(self, status_code, content, headers=None): if headers is None: headers = {} self.status_code = status_code if isinstance(content, dict): content = json.dumps(content) headers["content-type"] = "application/json" self.content = content.encode("utf8") self.headers = headers def json(self): return json.loads(self.text) def raise_for_status(self): pass @property def ok(self): return self.status_code // 100 == 2 @property def text(self): return self.content.decode("utf8") class mocked_response: def __init__(self, *responses, callback=None): self.callback = callback self.responses = list(responses) def __enter__(self): self.orig_get = requests.Session.get self.orig_post = requests.Session.post self.orig_request = requests.Session.request def mockable_request(f): def new_f(*args, **kwargs): if self.callback: response = self.callback(*args, **kwargs) if response is not None: return response if self.responses: resp = self.responses.pop(0) if isinstance(resp, dict): resp = MockedResponse(200, resp) return resp return f(*args, **kwargs) return Mock(side_effect=new_f) requests.Session.get = mockable_request(requests.Session.get) requests.Session.post = mockable_request(requests.Session.post) requests.Session.request = mockable_request(requests.Session.request) def __exit__(self, type, value, traceback): requests.Session.get = self.orig_get requests.Session.post = self.orig_post requests.Session.request = self.orig_request class BasicTests(TestCase): def setUp(self): self.factory = RequestFactory() def test_generate_unique_username(self): examples = [ ("a.b-c@example.com", "a.b-c"), ("Üsêrnamê", "username"), ("User Name", "user_name"), ("", "user"), ] for input, username in examples: self.assertEqual(utils.generate_unique_username([input]), username) def test_email_validation(self): s = "this.email.address.is.a.bit.too.long.but.should.still.validate@example.com" # noqa self.assertEqual(s, utils.valid_email_or_none(s)) def test_serializer(self): class SomeValue: pass some_value = SomeValue() class SomeField(models.Field): def get_prep_value(self, value): return "somevalue" def from_db_value(self, value, expression, connection): return some_value class SomeModel(models.Model): dt = models.DateTimeField() t = models.TimeField() d = models.DateField() img1 = models.ImageField() img2 = models.ImageField() img3 = models.ImageField() something = SomeField() def method(self): pass instance = SomeModel( dt=datetime.now(), d=date.today(), something=some_value, t=datetime.now().time(), ) instance.img1 = ContentFile(b"%PDF", name="foo.pdf") instance.img2 = ContentFile( b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00" b"\x00\x00\x007n\xf9$\x00\x00\x00\nIDATx\x9cc`\x00\x00\x00\x02\x00\x01H\xaf" b"\xa4q\x00\x00\x00\x00IEND\xaeB`\x82", name="foo.png", ) # make sure serializer doesn't fail if a method is attached to # the instance instance.method = method instance.nonfield = "hello" data = utils.serialize_instance(instance) instance2 = utils.deserialize_instance(SomeModel, data) self.assertEqual(getattr(instance, "method", None), method) self.assertEqual(getattr(instance2, "method", None), None) self.assertEqual(instance2.something, some_value) self.assertEqual(instance2.img1.name, "foo.pdf") self.assertEqual(instance2.img2.name, "foo.png") self.assertEqual(instance2.img3.name, "") self.assertEqual(instance.nonfield, instance2.nonfield) self.assertEqual(instance.d, instance2.d) self.assertEqual(instance.dt.date(), instance2.dt.date()) for t1, t2 in [ (instance.t, instance2.t), (instance.dt.time(), instance2.dt.time()), ]: self.assertEqual(t1.hour, t2.hour) self.assertEqual(t1.minute, t2.minute) self.assertEqual(t1.second, t2.second) # AssertionError: datetime.time(10, 6, 28, 705776) # != datetime.time(10, 6, 28, 705000) self.assertEqual(int(t1.microsecond / 1000), int(t2.microsecond / 1000)) def test_serializer_binary_field(self): class SomeBinaryModel(models.Model): bb = models.BinaryField() bb_empty = models.BinaryField() instance = SomeBinaryModel(bb=b"some binary data") serialized = utils.serialize_instance(instance) deserialized = utils.deserialize_instance(SomeBinaryModel, serialized) self.assertEqual(serialized["bb"], "c29tZSBiaW5hcnkgZGF0YQ==") self.assertEqual(serialized["bb_empty"], "") self.assertEqual(deserialized.bb, b"some binary data") self.assertEqual(deserialized.bb_empty, b"") def test_build_absolute_uri(self): request = None if not app_settings.SITES_ENABLED: request = self.factory.get("/") request.META["SERVER_NAME"] = "example.com" self.assertEqual( utils.build_absolute_uri(request, "/foo"), "http://example.com/foo" ) self.assertEqual( utils.build_absolute_uri(request, "/foo", protocol="ftp"), "ftp://example.com/foo", ) self.assertEqual( utils.build_absolute_uri(request, "http://foo.com/bar"), "http://foo.com/bar", ) def test_int_to_base36(self): n = 55798679658823689999 b36 = "brxk553wvxbf3" assert int_to_base36(n) == b36 assert base36_to_int(b36) == n def test_templatetag_with_csrf_failure(self): # Generate a fictitious GET request from allauth.socialaccount.models import SocialApp app = SocialApp.objects.create(provider="google") if app_settings.SITES_ENABLED: from django.contrib.sites.models import Site app.sites.add(Site.objects.get_current()) request = self.factory.get("/tests/test_403_csrf.html") # Simulate a CSRF failure by calling the View directly # This template is using the `provider_login_url` templatetag response = csrf.csrf_failure(request, template_name="tests/test_403_csrf.html") # Ensure that CSRF failures with this template # tag succeed with the expected 403 response self.assertEqual(response.status_code, 403) django-allauth-65.0.2/allauth/urls.py000066400000000000000000000051151467545753200175130ustar00rootroot00000000000000from importlib import import_module from typing import List, Union from django.urls import URLPattern, URLResolver, include, path from django.views.generic.base import RedirectView from allauth.socialaccount import providers from . import app_settings def build_provider_urlpatterns() -> List[Union[URLPattern, URLResolver]]: # Provider urlpatterns, as separate attribute (for reusability). provider_urlpatterns: List[Union[URLPattern, URLResolver]] = [] provider_classes = providers.registry.get_class_list() # We need to move the OpenID Connect provider to the end. The reason is that # matches URLs that the builtin providers also match. # # NOTE: Only needed if OPENID_CONNECT_URL_PREFIX is blank. provider_classes = [ cls for cls in provider_classes if cls.id != "openid_connect" ] + [cls for cls in provider_classes if cls.id == "openid_connect"] for provider_class in provider_classes: prov_mod = import_module(provider_class.get_package() + ".urls") prov_urlpatterns = getattr(prov_mod, "urlpatterns", None) if prov_urlpatterns: provider_urlpatterns += prov_urlpatterns return provider_urlpatterns urlpatterns: List[Union[URLPattern, URLResolver]] = [] if not app_settings.HEADLESS_ONLY: urlpatterns += [path("", include("allauth.account.urls"))] if app_settings.MFA_ENABLED: urlpatterns += [path("2fa/", include("allauth.mfa.urls"))] if app_settings.SOCIALACCOUNT_ENABLED and not app_settings.HEADLESS_ONLY: urlpatterns += [path("3rdparty/", include("allauth.socialaccount.urls"))] # DEPRECATED! -- deal with legacy URLs urlpatterns += [ path( "social/login/cancelled/", RedirectView.as_view( pattern_name="socialaccount_login_cancelled", permanent=True ), ), path( "social/login/error/", RedirectView.as_view( pattern_name="socialaccount_login_error", permanent=True ), ), path( "social/signup/", RedirectView.as_view(pattern_name="socialaccount_signup", permanent=True), ), path( "social/connections/", RedirectView.as_view( pattern_name="socialaccount_connections", permanent=True ), ), ] # (end DEPRECATED) if app_settings.SOCIALACCOUNT_ENABLED: urlpatterns += build_provider_urlpatterns() if app_settings.USERSESSIONS_ENABLED and not app_settings.HEADLESS_ONLY: urlpatterns += [path("sessions/", include("allauth.usersessions.urls"))] django-allauth-65.0.2/allauth/usersessions/000077500000000000000000000000001467545753200207175ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/__init__.py000066400000000000000000000000001467545753200230160ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/adapter.py000066400000000000000000000013111467545753200227050ustar00rootroot00000000000000from allauth.core.internal.adapter import BaseAdapter from allauth.usersessions import app_settings from allauth.utils import import_attribute class DefaultUserSessionsAdapter(BaseAdapter): """The adapter class allows you to override various functionality of the ``allauth.usersessions`` app. To do so, point ``settings.USERSESSIONS_ADAPTER`` to your own class that derives from ``DefaultUserSessionsAdapter`` and override the behavior by altering the implementation of the methods according to your own needs. """ def end_sessions(self, sessions): for session in sessions: session.end() def get_adapter(): return import_attribute(app_settings.ADAPTER)() django-allauth-65.0.2/allauth/usersessions/admin.py000066400000000000000000000004131467545753200223570ustar00rootroot00000000000000from django.contrib import admin from allauth.usersessions.models import UserSession @admin.register(UserSession) class UserSessionAdmin(admin.ModelAdmin): raw_id_fields = ("user",) list_display = ("user", "created_at", "last_seen_at", "ip", "user_agent") django-allauth-65.0.2/allauth/usersessions/app_settings.py000066400000000000000000000014641467545753200237760ustar00rootroot00000000000000class AppSettings: def __init__(self, prefix): self.prefix = prefix def _setting(self, name, dflt): from allauth.utils import get_setting return get_setting(self.prefix + name, dflt) @property def ADAPTER(self): return self._setting( "ADAPTER", "allauth.usersessions.adapter.DefaultUserSessionsAdapter" ) @property def TRACK_ACTIVITY(self): """Whether or not sessions are to be actively tracked. When tracking is enabled, the last seen IP address and last seen timestamp will be kept track of. """ return self._setting("TRACK_ACTIVITY", False) _app_settings = AppSettings("USERSESSIONS_") def __getattr__(name): # See https://peps.python.org/pep-0562/ return getattr(_app_settings, name) django-allauth-65.0.2/allauth/usersessions/apps.py000066400000000000000000000013401467545753200222320ustar00rootroot00000000000000from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ from allauth import app_settings class UserSessionsConfig(AppConfig): name = "allauth.usersessions" verbose_name = _("User Sessions") default_auto_field = ( app_settings.DEFAULT_AUTO_FIELD or "django.db.models.BigAutoField" ) def ready(self): from allauth.account.signals import ( password_changed, password_set, user_logged_in, ) from allauth.usersessions import signals user_logged_in.connect(receiver=signals.on_user_logged_in) for sig in [password_set, password_changed]: sig.connect(receiver=signals.on_password_changed) django-allauth-65.0.2/allauth/usersessions/forms.py000066400000000000000000000005251467545753200224210ustar00rootroot00000000000000from django import forms from allauth.usersessions.internal import flows class ManageUserSessionsForm(forms.Form): def __init__(self, *args, **kwargs): self.request = kwargs.pop("request") super().__init__(*args, **kwargs) def save(self, request): flows.sessions.end_other_sessions(request, request.user) django-allauth-65.0.2/allauth/usersessions/internal/000077500000000000000000000000001467545753200225335ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/internal/__init__.py000066400000000000000000000000001467545753200246320ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/internal/flows/000077500000000000000000000000001467545753200236655ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/internal/flows/__init__.py000066400000000000000000000001221467545753200257710ustar00rootroot00000000000000from allauth.usersessions.internal.flows import sessions __all__ = ["sessions"] django-allauth-65.0.2/allauth/usersessions/internal/flows/sessions.py000066400000000000000000000011501467545753200261020ustar00rootroot00000000000000from allauth.account.internal import flows from allauth.usersessions.adapter import get_adapter from allauth.usersessions.models import UserSession def end_other_sessions(request, user): sessions_to_end = [] for session in UserSession.objects.filter(user=user): if session.is_current(): continue sessions_to_end.append(session) end_sessions(request, sessions_to_end) def end_sessions(request, sessions): has_current = any([session.is_current() for session in sessions]) get_adapter().end_sessions(sessions) if has_current: flows.logout.logout(request) django-allauth-65.0.2/allauth/usersessions/middleware.py000066400000000000000000000011451467545753200234070ustar00rootroot00000000000000from allauth.usersessions import app_settings from allauth.usersessions.models import UserSession class UserSessionsMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): if ( app_settings.TRACK_ACTIVITY and hasattr(request, "session") and request.session.session_key and hasattr(request, "user") and request.user.is_authenticated ): UserSession.objects.create_from_request(request) response = self.get_response(request) return response django-allauth-65.0.2/allauth/usersessions/migrations/000077500000000000000000000000001467545753200230735ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/migrations/0001_initial.py000066400000000000000000000033161467545753200255410ustar00rootroot00000000000000# Generated by Django 4.2.6 on 2023-12-05 11:44 import django.db.models.deletion import django.utils.timezone from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name="UserSession", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ("created_at", models.DateTimeField(default=django.utils.timezone.now)), ("ip", models.GenericIPAddressField()), ( "last_seen_at", models.DateTimeField(default=django.utils.timezone.now), ), ( "session_key", models.CharField( editable=False, max_length=40, unique=True, verbose_name="session key", ), ), ("user_agent", models.CharField(max_length=200)), ("data", models.JSONField(default=dict)), ( "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), ], ), ] django-allauth-65.0.2/allauth/usersessions/migrations/__init__.py000066400000000000000000000000001467545753200251720ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/models.py000066400000000000000000000104201467545753200225510ustar00rootroot00000000000000from importlib import import_module from django.conf import settings from django.contrib.auth import get_user from django.core.exceptions import ImproperlyConfigured from django.db import models, transaction from django.http import HttpRequest from django.utils import timezone from django.utils.translation import gettext_lazy as _ from allauth import app_settings as allauth_settings from allauth.account.adapter import get_adapter from allauth.core import context if not allauth_settings.USERSESSIONS_ENABLED: raise ImproperlyConfigured( "allauth.usersessions not installed, yet its models are imported." ) class UserSessionManager(models.Manager): def purge_and_list(self, user): ret = [] sessions = UserSession.objects.filter(user=user) for session in sessions.iterator(): if not session.purge(): ret.append(session) return ret def create_from_request(self, request): if not request.user.is_authenticated: raise ValueError() if not request.session.session_key: request.session.save() ua = request.META.get("HTTP_USER_AGENT", "")[ 0 : UserSession._meta.get_field("user_agent").max_length ] defaults = dict( user=request.user, ip=get_adapter().get_client_ip(request), user_agent=ua, ) from_session = None with transaction.atomic(): from allauth.usersessions.signals import session_client_changed session, created = UserSession.objects.get_or_create( session_key=request.session.session_key, defaults=defaults ) if not created: from_session = UserSession( session_key=session.session_key, user=session.user, ip=session.ip, user_agent=session.user_agent, data=session.data, created_at=session.created_at, last_seen_at=session.last_seen_at, ) # Update session session.user = defaults["user"] session.ip = defaults["ip"] session.user_agent = defaults["user_agent"] session.last_seen_at = timezone.now() session.save() if from_session and ( from_session.ip != session.ip or from_session.user_agent != session.user_agent ): session_client_changed.send( sender=UserSession, request=request, from_session=from_session, to_session=session, ) class UserSession(models.Model): objects = UserSessionManager() user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) created_at = models.DateTimeField(default=timezone.now) ip = models.GenericIPAddressField() last_seen_at = models.DateTimeField(default=timezone.now) session_key = models.CharField( _("session key"), max_length=40, unique=True, editable=False ) user_agent = models.CharField(max_length=200) data = models.JSONField(default=dict) def __str__(self): return f"{self.ip} ({self.user_agent})" def _session_store(self, *args): engine = import_module(settings.SESSION_ENGINE) return engine.SessionStore(*args) def exists(self): return self._session_store().exists(self.session_key) def purge(self): purge = not self.exists() if not purge: # Even if the session still exists, it might be the case that the # user session hash is out of sync. So, let's see if # `django.contrib.auth` can find a user... request = HttpRequest() request.session = self._session_store(self.session_key) user = get_user(request) purge = not user or user.is_anonymous if purge: self.delete() return True return False def is_current(self): return self.session_key == context.request.session.session_key def end(self): engine = import_module(settings.SESSION_ENGINE) store = engine.SessionStore() store.delete(self.session_key) self.delete() django-allauth-65.0.2/allauth/usersessions/signals.py000066400000000000000000000010201467545753200227220ustar00rootroot00000000000000from django.dispatch import Signal from allauth.account import app_settings from .models import UserSession # Provides the arguments "request", "from_session", "to_session" session_client_changed = Signal() def on_user_logged_in(sender, **kwargs): request = kwargs["request"] UserSession.objects.create_from_request(request) def on_password_changed(sender, **kwargs): if not app_settings.LOGOUT_ON_PASSWORD_CHANGE: request = kwargs["request"] UserSession.objects.create_from_request(request) django-allauth-65.0.2/allauth/usersessions/tests/000077500000000000000000000000001467545753200220615ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/tests/__init__.py000066400000000000000000000000001467545753200241600ustar00rootroot00000000000000django-allauth-65.0.2/allauth/usersessions/tests/test_middleware.py000066400000000000000000000057521467545753200256200ustar00rootroot00000000000000from unittest.mock import Mock from django.contrib.auth.models import AnonymousUser from django.test.utils import override_settings import pytest from allauth.usersessions.middleware import UserSessionsMiddleware from allauth.usersessions.models import UserSession from allauth.usersessions.signals import session_client_changed def test_mw_without_request_user(rf, db, settings): settings.USERSESSIONS_TRACK_ACTIVITY = True mw = UserSessionsMiddleware(lambda request: None) request = rf.get("/") mw(request) assert UserSession.objects.count() == 0 @pytest.mark.parametrize("track_activity", [False, True]) def test_mw_with_request_user(rf, db, settings, user, track_activity): settings.USERSESSIONS_TRACK_ACTIVITY = track_activity mw = UserSessionsMiddleware(lambda request: None) request = rf.get("/") request.user = user request.session = Mock() request.session.session_key = "sess-123" mw(request) assert ( UserSession.objects.filter(session_key="sess-123", user=user).exists() is track_activity ) def test_mw_with_anonymous_request_user(rf, db, settings): settings.USERSESSIONS_TRACK_ACTIVITY = True mw = UserSessionsMiddleware(lambda request: None) request = rf.get("/") request.user = AnonymousUser() request.session = Mock() request.session.session_key = "sess-123" mw(request) assert not UserSession.objects.exists() @override_settings(USERSESSIONS_TRACK_ACTIVITY=True) def test_mw_change_ip_and_useragent(rf, db, user): mw = UserSessionsMiddleware(lambda request: None) # First request request1 = rf.get("/") request1.user = user request1.session = Mock() request1.session.session_key = "sess-123" request1.META["HTTP_USER_AGENT"] = "Old User Agent" request1.META["REMOTE_ADDR"] = "1.1.1.1" mw(request1) # Second request with changed IP and User Agent request2 = rf.get("/") request2.user = user request2.session = Mock() request2.session.session_key = "sess-123" request2.META["HTTP_USER_AGENT"] = "New User Agent" request2.META["REMOTE_ADDR"] = "2.2.2.2" # Set up signal receiver signal_received = [] def signal_handler(sender, request, from_session, to_session, **kwargs): signal_received.append((from_session, to_session)) session_client_changed.connect(signal_handler) # Process second request mw(request2) # Check if UserSession was updated user_session = UserSession.objects.get(session_key="sess-123", user=user) assert user_session.ip == "2.2.2.2" assert user_session.user_agent == "New User Agent" # Check if signal was triggered assert len(signal_received) == 1 from_session, to_session = signal_received[0] assert from_session.ip == "1.1.1.1" assert from_session.user_agent == "Old User Agent" assert to_session.ip == "2.2.2.2" assert to_session.user_agent == "New User Agent" # Clean up signal connection session_client_changed.disconnect(signal_handler) django-allauth-65.0.2/allauth/usersessions/tests/test_views.py000066400000000000000000000042621467545753200246330ustar00rootroot00000000000000from django.test import Client from django.urls import reverse import pytest from allauth.usersessions.models import UserSession def test_overall_flow(user, user_password): firefox = Client(HTTP_USER_AGENT="Mozilla Firefox") nyxt = Client(HTTP_USER_AGENT="Nyxt") for client in [firefox, nyxt]: resp = client.post( reverse("account_login"), {"login": user.username, "password": user_password}, ) assert resp.status_code == 302 assert UserSession.objects.filter(user=user).count() == 2 sessions = list(UserSession.objects.filter(user=user).order_by("pk")) assert sessions[0].user_agent == "Mozilla Firefox" assert sessions[1].user_agent == "Nyxt" for client in [firefox, nyxt]: resp = client.get(reverse("usersessions_list")) assert resp.status_code == 200 resp = firefox.post(reverse("usersessions_list")) assert resp.status_code == 302 assert UserSession.objects.filter(user=user).count() == 1 assert UserSession.objects.filter(user=user, pk=sessions[0].pk).exists() assert not UserSession.objects.filter(user=user, pk=sessions[1].pk).exists() resp = nyxt.get(reverse("usersessions_list")) assert resp.status_code == 302 assert resp["location"] == reverse("account_login") + "?next=" + reverse( "usersessions_list" ) @pytest.mark.parametrize("logout_on_passwd_change", [True, False]) def test_change_password_updates_user_session( settings, logout_on_passwd_change, client, user, user_password, password_factory ): settings.ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = logout_on_passwd_change resp = client.post( reverse("account_login"), {"login": user.username, "password": user_password}, ) assert resp.status_code == 302 assert len(UserSession.objects.purge_and_list(user)) == 1 new_password = password_factory() resp = client.post( reverse("account_change_password"), { "oldpassword": user_password, "password1": new_password, "password2": new_password, }, ) assert len(UserSession.objects.purge_and_list(user)) == ( 0 if logout_on_passwd_change else 1 ) django-allauth-65.0.2/allauth/usersessions/urls.py000066400000000000000000000002321467545753200222530ustar00rootroot00000000000000from django.urls import path from allauth.usersessions import views urlpatterns = [ path("", views.list_usersessions, name="usersessions_list"), ] django-allauth-65.0.2/allauth/usersessions/views.py000066400000000000000000000032021467545753200224230ustar00rootroot00000000000000from django.contrib import messages from django.contrib.auth.decorators import login_required from django.urls import reverse_lazy from django.utils.decorators import method_decorator from django.views.generic.edit import FormView from allauth.account import app_settings as account_settings from allauth.account.adapter import get_adapter as get_account_adapter from allauth.usersessions import app_settings from allauth.usersessions.forms import ManageUserSessionsForm from allauth.usersessions.models import UserSession @method_decorator(login_required, name="dispatch") class ListUserSessionsView(FormView): template_name = ( "usersessions/usersession_list." + account_settings.TEMPLATE_EXTENSION ) form_class = ManageUserSessionsForm success_url = reverse_lazy("usersessions_list") def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) sessions = sorted( UserSession.objects.purge_and_list(self.request.user), key=lambda s: s.created_at, ) ret["sessions"] = sessions ret["session_count"] = len(sessions) ret["show_last_seen_at"] = app_settings.TRACK_ACTIVITY return ret def get_form_kwargs(self): ret = super().get_form_kwargs() ret["request"] = self.request return ret def form_valid(self, form): form.save(self.request) get_account_adapter().add_message( self.request, messages.INFO, "usersessions/messages/sessions_logged_out.txt", ) return super().form_valid(form) list_usersessions = ListUserSessionsView.as_view() django-allauth-65.0.2/allauth/utils.py000066400000000000000000000257601467545753200176760ustar00rootroot00000000000000import base64 import importlib import json import random import re import string import unicodedata from collections import OrderedDict from urllib.parse import urlsplit from django.conf import settings from django.contrib.auth import get_user_model from django.core.exceptions import ( FieldDoesNotExist, ImproperlyConfigured, ValidationError, ) from django.core.files.base import ContentFile from django.core.serializers.json import DjangoJSONEncoder from django.core.validators import validate_email from django.db.models import FileField from django.db.models.fields import ( BinaryField, DateField, DateTimeField, EmailField, TimeField, ) from django.utils import dateparse from django.utils.encoding import force_bytes, force_str from allauth import app_settings # Magic number 7: if you run into collisions with this number, then you are # of big enough scale to start investing in a decent user model... MAX_USERNAME_SUFFIX_LENGTH = 7 USERNAME_SUFFIX_CHARS = [string.digits] * 4 + [string.ascii_letters] * ( MAX_USERNAME_SUFFIX_LENGTH - 4 ) def _generate_unique_username_base(txts, regex=None): from .account.adapter import get_adapter adapter = get_adapter() username = None regex = regex or r"[^\w\s@+.-]" for txt in txts: if not txt: continue username = unicodedata.normalize("NFKD", force_str(txt)) username = username.encode("ascii", "ignore").decode("ascii") if len(username) == 0: continue username = force_str(re.sub(regex, "", username).lower()) # Django allows for '@' in usernames in order to accommodate for # project wanting to use email for username. In allauth we don't # use this, we already have a proper place for putting email # addresses (EmailAddress), so let's not use the full email # address and only take the part leading up to the '@'. username = username.split("@")[0] username = username.strip() username = re.sub(r"\s+", "_", username) # Finally, validating base username without database lookups etc. try: username = adapter.clean_username(username, shallow=True) break except ValidationError: pass return username or "user" def get_username_max_length(): from .account.app_settings import USER_MODEL_USERNAME_FIELD if USER_MODEL_USERNAME_FIELD is not None: User = get_user_model() max_length = User._meta.get_field(USER_MODEL_USERNAME_FIELD).max_length else: max_length = 0 return max_length def generate_username_candidate(basename, suffix_length): max_length = get_username_max_length() suffix = "".join( random.choice(USERNAME_SUFFIX_CHARS[i]) for i in range(suffix_length) ) return basename[0 : max_length - len(suffix)] + suffix def generate_username_candidates(basename): from .account.app_settings import USERNAME_MIN_LENGTH if len(basename) >= USERNAME_MIN_LENGTH: ret = [basename] else: ret = [] min_suffix_length = max(1, USERNAME_MIN_LENGTH - len(basename)) max_suffix_length = min(get_username_max_length(), MAX_USERNAME_SUFFIX_LENGTH) for suffix_length in range(min_suffix_length, max_suffix_length): ret.append(generate_username_candidate(basename, suffix_length)) return ret def generate_unique_username(txts, regex=None): from allauth.account.utils import filter_users_by_username from .account.adapter import get_adapter from .account.app_settings import USER_MODEL_USERNAME_FIELD adapter = get_adapter() basename = _generate_unique_username_base(txts, regex) candidates = generate_username_candidates(basename) existing_usernames = filter_users_by_username(*candidates).values_list( USER_MODEL_USERNAME_FIELD, flat=True ) existing_usernames = set([n.lower() for n in existing_usernames]) for candidate in candidates: if candidate.lower() not in existing_usernames: try: return adapter.clean_username(candidate, shallow=True) except ValidationError: pass # This really should not happen raise NotImplementedError("Unable to find a unique username") def valid_email_or_none(email): ret = None try: if email: validate_email(email) if len(email) <= EmailField().max_length: ret = email.lower() except ValidationError: pass return ret def import_attribute(path): assert isinstance(path, str) pkg, attr = path.rsplit(".", 1) ret = getattr(importlib.import_module(pkg), attr) return ret def import_callable(path_or_callable): if not callable(path_or_callable): ret = import_attribute(path_or_callable) else: ret = path_or_callable return ret SERIALIZED_DB_FIELD_PREFIX = "_db_" def serialize_instance(instance): """ Since Django 1.6 items added to the session are no longer pickled, but JSON encoded by default. We are storing partially complete models in the session (user, account, token, ...). We cannot use standard Django serialization, as these are models are not "complete" yet. Serialization will start complaining about missing relations et al. """ data = {} for k, v in instance.__dict__.items(): if k.startswith("_") or callable(v): continue try: field = instance._meta.get_field(k) if isinstance(field, BinaryField): if v is not None: v = force_str(base64.b64encode(v)) elif isinstance(field, FileField): if v and not isinstance(v, str): v = { "name": v.name, "content": base64.b64encode(v.read()).decode("ascii"), } # Check if the field is serializable. If not, we'll fall back # to serializing the DB values which should cover most use cases. try: json.dumps(v, cls=DjangoJSONEncoder) except TypeError: v = field.get_prep_value(v) k = SERIALIZED_DB_FIELD_PREFIX + k except FieldDoesNotExist: pass data[k] = v return json.loads(json.dumps(data, cls=DjangoJSONEncoder)) def deserialize_instance(model, data): ret = model() for k, v in data.items(): is_db_value = False if k.startswith(SERIALIZED_DB_FIELD_PREFIX): k = k[len(SERIALIZED_DB_FIELD_PREFIX) :] is_db_value = True if v is not None: try: f = model._meta.get_field(k) if isinstance(f, DateTimeField): v = dateparse.parse_datetime(v) elif isinstance(f, TimeField): v = dateparse.parse_time(v) elif isinstance(f, DateField): v = dateparse.parse_date(v) elif isinstance(f, BinaryField): v = force_bytes(base64.b64decode(force_bytes(v))) elif isinstance(f, FileField): if isinstance(v, dict): v = ContentFile(base64.b64decode(v["content"]), name=v["name"]) elif is_db_value: try: # This is quite an ugly hack, but will cover most # use cases... # The signature of `from_db_value` changed in Django 3 # https://docs.djangoproject.com/en/3.0/releases/3.0/#features-removed-in-3-0 v = f.from_db_value(v, None, None) except Exception: raise ImproperlyConfigured( "Unable to auto serialize field '{}', custom" " serialization override required".format(k) ) except FieldDoesNotExist: pass setattr(ret, k, v) return ret def set_form_field_order(form, field_order): """ This function is a verbatim copy of django.forms.Form.order_fields() to support field ordering below Django 1.9. field_order is a list of field names specifying the order. Append fields not included in the list in the default order for backward compatibility with subclasses not overriding field_order. If field_order is None, keep all fields in the order defined in the class. Ignore unknown fields in field_order to allow disabling fields in form subclasses without redefining ordering. """ if field_order is None: return fields = OrderedDict() for key in field_order: try: fields[key] = form.fields.pop(key) except KeyError: # ignore unknown fields pass fields.update(form.fields) # add remaining fields in original order form.fields = fields def build_absolute_uri(request, location, protocol=None): """request.build_absolute_uri() helper Like request.build_absolute_uri, but gracefully handling the case where request is None. """ from .account import app_settings as account_settings if request is None: if not app_settings.SITES_ENABLED: raise ImproperlyConfigured( "Passing `request=None` requires `sites` to be enabled." ) from django.contrib.sites.models import Site site = Site.objects.get_current() bits = urlsplit(location) if not (bits.scheme and bits.netloc): uri = "{proto}://{domain}{url}".format( proto=account_settings.DEFAULT_HTTP_PROTOCOL, domain=site.domain, url=location, ) else: uri = location else: uri = request.build_absolute_uri(location) # NOTE: We only force a protocol if we are instructed to do so # (via the `protocol` parameter, or, if the default is set to # HTTPS. The latter keeps compatibility with the debatable use # case of running your site under both HTTP and HTTPS, where one # would want to make sure HTTPS links end up in password reset # mails even while they were initiated on an HTTP password reset # form. if not protocol and account_settings.DEFAULT_HTTP_PROTOCOL == "https": protocol = account_settings.DEFAULT_HTTP_PROTOCOL # (end NOTE) if protocol: uri = protocol + ":" + uri.partition(":")[2] return uri def get_form_class(forms, form_id, default_form): form_class = forms.get(form_id, default_form) if isinstance(form_class, str): form_class = import_attribute(form_class) return form_class def get_request_param(request, param, default=None): if request is None: return default return request.POST.get(param) or request.GET.get(param, default) def get_setting(name, dflt): getter = getattr( settings, "ALLAUTH_SETTING_GETTER", lambda name, dflt: getattr(settings, name, dflt), ) getter = import_callable(getter) return getter(name, dflt) django-allauth-65.0.2/docs/000077500000000000000000000000001467545753200154505ustar00rootroot00000000000000django-allauth-65.0.2/docs/Makefile000066400000000000000000000127341467545753200171170ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-allauth.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-allauth.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/django-allauth" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-allauth" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." django-allauth-65.0.2/docs/account/000077500000000000000000000000001467545753200171045ustar00rootroot00000000000000django-allauth-65.0.2/docs/account/adapter.rst000066400000000000000000000001331467545753200212530ustar00rootroot00000000000000Adapter ======= .. autoclass:: allauth.account.adapter.DefaultAccountAdapter :members: django-allauth-65.0.2/docs/account/advanced.rst000066400000000000000000000104311467545753200214020ustar00rootroot00000000000000Advanced Usage ============== Custom User Models ------------------ If you use a custom user model you need to specify what field represents the ``username``, if any. Here, ``username`` really refers to the field representing the nickname that the user uses to login, and not to some unique identifier (possibly including an email address) as is the case for Django's ``AbstractBaseUser.USERNAME_FIELD``. Therefore, if your custom user model does not have a ``username`` field (again, not to be mistaken with an email address or user id), you will need to set ``ACCOUNT_USER_MODEL_USERNAME_FIELD`` to ``None``. This will disable username related functionality in ``allauth``. Remember to also set ``ACCOUNT_USERNAME_REQUIRED`` to ``False``. Similarly, you will need to set ``ACCOUNT_USER_MODEL_EMAIL_FIELD`` to ``None`` or to the proper field (if other than ``email``). For example, if you want to use a custom user model that has ``email`` as the identifying field, and you don't want to collect usernames, you need the following in your settings.py:: ACCOUNT_USER_MODEL_USERNAME_FIELD = None ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_AUTHENTICATION_METHOD = 'email' Creating and Populating User instances -------------------------------------- The following adapter methods can be used to intervene in how User instances are created and populated with data - ``allauth.account.adapter.DefaultAccountAdapter``: - ``is_open_for_signup(self, request)``: The default function returns ``True``. You can override this method by returning ``False`` if you want to disable account signup. - ``new_user(self, request)``: Instantiates a new, empty ``User``. - ``save_user(self, request, user, form)``: Populates and saves the ``User`` instance using information provided in the signup form. - ``populate_username(self, request, user)``: Fills in a valid username, if required and missing. If the username is already present, then it is assumed to be valid (unique). - ``confirm_email(self, request, email_address)``: Marks the email address as confirmed and saves to the db. - ``generate_unique_username(self, txts, regex=None)``: Returns a unique username from the combination of strings present in txts iterable. A regex pattern can be passed to the method to make sure the generated username matches it. Invitations ----------- Invitation handling is not supported, and most likely will not be any time soon. An invitation app could cover anything ranging from invitations of new users, to invitations of existing users to participate in restricted parts of the site. All in all, the scope of invitation handling is large enough to warrant being addressed in an app of its own. Still, everything is in place to easily hook up any third party invitation app. The account adapter (``allauth.account.adapter.DefaultAccountAdapter``) offers the following methods: - ``is_open_for_signup(self, request)``. You can override this method to, for example, inspect the session to check if an invitation was accepted. - ``stash_verified_email(self, request, email)``. If an invitation was accepted by following a link in an email, then there is no need to send email verification mails after the signup is completed. Use this method to record the fact that an email address was verified. Custom Redirects ---------------- If redirecting to statically configurable URLs (as specified in your project settings) is not flexible enough, then you can override the following adapter methods: - ``allauth.account.adapter.DefaultAccountAdapter``: - ``get_login_redirect_url(self, request)`` - ``get_logout_redirect_url(self, request)`` - ``get_email_verification_redirect_url(self, email_address)`` - ``get_signup_redirect_url(self, request)`` For example, redirecting to ``/accounts//`` can be implemented as follows:: # project/settings.py: ACCOUNT_ADAPTER = 'project.users.adapter.MyAccountAdapter' # project/users/adapter.py: from django.conf import settings from allauth.account.adapter import DefaultAccountAdapter class MyAccountAdapter(DefaultAccountAdapter): def get_login_redirect_url(self, request): path = "/accounts/{username}/" return path.format(username=request.user.username) django-allauth-65.0.2/docs/account/configuration.rst000066400000000000000000000406541467545753200225160ustar00rootroot00000000000000Configuration ============= Available settings: ``ACCOUNT_ADAPTER`` (default: ``"allauth.account.adapter.DefaultAccountAdapter"``) Specifies the adapter class to use, allowing you to alter certain default behaviour. ``ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS`` (default: ``True``) The default behaviour is to redirect authenticated users to ``LOGIN_REDIRECT_URL`` when they try accessing login/signup pages. By changing this setting to ``False``, logged in users will not be redirected when they access login/signup pages. ``ACCOUNT_AUTHENTICATION_METHOD`` (default: ``"username"``, alternatives: ``"email"`` or ``"username_email"``) Specifies the login method to use -- whether the user logs in by entering their username, email address, or either one of both. Setting this to ``"email"`` requires ``ACCOUNT_EMAIL_REQUIRED=True`` ``ACCOUNT_CHANGE_EMAIL`` (default: ``False``) When disabled (``False``), users can add one or more email addresses (up to a maximum of ``ACCOUNT_MAX_EMAIL_ADDRESSES``) to their account and freely manage those email addresses. When enabled (``True``), users are limited to having exactly one email address that they can change by adding a temporary second email address that, when verified, replaces the current email address. ``ACCOUNT_CONFIRM_EMAIL_ON_GET`` (default: ``False``) Determines whether or not an email address is automatically confirmed by a GET request. `GET is not designed to modify the server state `_, though it is commonly used for email confirmation. To avoid requiring user interaction, consider using POST via Javascript in your email confirmation template as an alternative to setting this to True. ``ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL`` (default: ``settings.LOGIN_URL``) The URL to redirect to after a successful email confirmation, in case no user is logged in. ``ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL`` (default: ``None``) The URL to redirect to after a successful email confirmation, in case of an authenticated user. Set to ``None`` to use ``settings.LOGIN_REDIRECT_URL``. ``ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS`` (default: ``3``) Determines the expiration date of email confirmation mails (# of days). ``ACCOUNT_EMAIL_CONFIRMATION_HMAC`` (default: ``True``) In order to verify an email address a key is mailed identifying the email address to be verified. In previous versions, a record was stored in the database for each ongoing email confirmation, keeping track of these keys. Current versions use HMAC based keys that do not require server side state. ``ACCOUNT_EMAIL_NOTIFICATIONS`` (default: ``False``) When enabled, account related security notifications, such as "Your password was changed", including information on user agent / IP address from where the change originated, will be emailed. ``ACCOUNT_EMAIL_REQUIRED`` (default: ``False``) The user is required to hand over an email address when signing up. ``ACCOUNT_EMAIL_VERIFICATION`` (default: ``"optional"``) Determines the email verification method during signup -- choose one of ``"mandatory"``, ``"optional"``, or ``"none"``. Setting this to ``"mandatory"`` requires ``ACCOUNT_EMAIL_REQUIRED`` to be ``True``. When set to ``"mandatory"`` the user is blocked from logging in until the email address is verified. Choose ``"optional"`` or ``"none"`` to allow logins with an unverified email address. In case of ``"optional"``, the email verification mail is still sent, whereas in case of "none" no email verification mails are sent. ``ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED`` (default: ``False``) Constrols whether email verification is performed by means of following a link in the email (``False``), or by entering a code (``True``). ``ACCOUNT_EMAIL_VERIFICATION_BY_CODE_MAX_ATTEMPTS`` (default: ``3``) This setting controls the maximum number of attempts the user has at inputting a valid code. ``ACCOUNT_EMAIL_VERIFICATION_BY_CODE_TIMEOUT`` (default: ``900``) The code that is emailed has a limited life span. It expires this many seconds after which it was sent. ``ACCOUNT_EMAIL_SUBJECT_PREFIX`` (default: ``"[Site] "``) Subject-line prefix to use for email messages sent. By default, the name of the current ``Site`` (``django.contrib.sites``) is used. ``ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS`` (default: ``True``) Configures whether password reset attempts for email addresses which do not have an account result in sending an email. ``ACCOUNT_DEFAULT_HTTP_PROTOCOL`` (default: ``"http"``) The default protocol used for when generating URLs, e.g. for the password forgotten procedure. Note that this is a default only -- see the section on HTTPS for more information. ``ACCOUNT_EMAIL_MAX_LENGTH`` (default: ``254``) Maximum length of the email field. You won't need to alter this unless using MySQL with the InnoDB storage engine and the ``utf8mb4`` charset, and only in versions lower than 5.7.7, because the default InnoDB settings don't allow indexes bigger than 767 bytes. When using ``utf8mb4``, characters are 4-bytes wide, so at maximum column indexes can be 191 characters long (767/4). Unfortunately Django doesn't allow specifying index lengths, so the solution is to reduce the length in characters of indexed text fields. More information can be found at `MySQL's documentation on converting between 3-byte and 4-byte Unicode character sets `_. ``ACCOUNT_MAX_EMAIL_ADDRESSES`` (default: ``None``) The maximum amount of email addresses a user can associate to his account. It is safe to change this setting for an already running project -- it will not negatively affect users that already exceed the allowed amount. Note that if you set the maximum to 1, users will not be able to change their email address. ``ACCOUNT_FORMS`` Used to override the builtin forms. Defaults to:: ACCOUNT_FORMS = { 'add_email': 'allauth.account.forms.AddEmailForm', 'change_password': 'allauth.account.forms.ChangePasswordForm', 'confirm_login_code': 'allauth.account.forms.ConfirmLoginCodeForm', 'login': 'allauth.account.forms.LoginForm', 'request_login_code': 'allauth.account.forms.RequestLoginCodeForm', 'reset_password': 'allauth.account.forms.ResetPasswordForm', 'reset_password_from_key': 'allauth.account.forms.ResetPasswordKeyForm', 'set_password': 'allauth.account.forms.SetPasswordForm', 'signup': 'allauth.account.forms.SignupForm', 'user_token': 'allauth.account.forms.UserTokenForm', } ``ACCOUNT_LOGIN_BY_CODE_ENABLED`` (default: ``False``) "Login by email" offers an alternative method of logging in. Instead of entering an email address and accompanying password, the user only enters the email address. Then, a one-time code is sent to that email address which allows the user to login. This method is often referred to as "Magic Code Login". This setting controls whether or not this method of logging in is enabled. ``ACCOUNT_LOGIN_BY_CODE_MAX_ATTEMPTS`` (default: ``3``) This setting controls the maximum number of attempts the user has at inputting a valid code. ``ACCOUNT_LOGIN_BY_CODE_REQUIRED`` (default: ``False``) When enabled (in case of ``True``), every user logging in is required to input a login confirmation code sent by email. Alternatively, you can specify a set of authentication methods (``"password"``, ``"mfa"``, or ``"socialaccount"``) for which login codes are required. ``ACCOUNT_LOGIN_BY_CODE_TIMEOUT`` (default: ``180``) The code that is emailed has a limited life span. It expires this many seconds after which it was sent. ``ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION`` (default: ``False``) The default behavior is not log users in and to redirect them to ``ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL``. By changing this setting to ``True``, users will automatically be logged in once they confirm their email address. Note however that this only works when confirming the email address **immediately after signing up**, assuming users didn't close their browser or used some sort of private browsing mode. ``ACCOUNT_LOGIN_ON_PASSWORD_RESET`` (default: ``False``) By changing this setting to ``True``, users will automatically be logged in once they have reset their password. By default they are redirected to the password reset done page. ``ACCOUNT_LOGIN_TIMEOUT`` (default: ``900``) The maximum allowed time (in seconds) for a login to go through the various login stages. This limits, for example, the time span that the 2FA stage remains available. ``ACCOUNT_LOGOUT_ON_GET`` (default: ``False``) Determines whether or not the user is automatically logged out by a GET request. `GET is not designed to modify the server state `_, and in this case it can be dangerous. See `LogoutView in the documentation `_ for details. ``ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE`` (default: ``False``) Determines whether or not the user is automatically logged out after changing or setting their password. See documentation for `Django's session invalidation on password change `_. ``ACCOUNT_LOGOUT_REDIRECT_URL`` (default: ``settings.LOGOUT_REDIRECT_URL or "/"``) The URL (or URL name) to return to after the user logs out. Defaults to Django's ``LOGOUT_REDIRECT_URL``, unless that is empty, then ``"/"`` is used. ``ACCOUNT_PASSWORD_INPUT_RENDER_VALUE`` (default: ``False``) ``render_value`` parameter as passed to ``PasswordInput`` fields. ``ACCOUNT_PASSWORD_RESET_TOKEN_GENERATOR`` (default: ``"allauth.account.forms.EmailAwarePasswordResetTokenGenerator"``) A string pointing to a custom token generator (e.g. 'myapp.auth.CustomTokenGenerator') for password resets. This class should implement the same methods as ``django.contrib.auth.tokens.PasswordResetTokenGenerator`` or subclass it. ``ACCOUNT_PRESERVE_USERNAME_CASING`` (default: ``True``) This setting determines whether the username is stored in lowercase (``False``) or whether its casing is to be preserved (``True``). Note that when casing is preserved, potentially expensive ``__iexact`` lookups are performed when filter on username. For now, the default is set to ``True`` to maintain backwards compatibility. ``ACCOUNT_PREVENT_ENUMERATION`` (default: ``True``) Controls whether or not information is revealed about whether or not a user account exists. For example, by entering random email addresses in the password reset form you can test whether or not those email addresses are associated with an account. Enabling this setting prevents that, and an email is always sent, regardless of whether or not the account exists. Note that there is a slight usability tax to pay because there is no immediate feedback. Whether or not enumeration can be prevented during signup depends on the email verification method. In case of mandatory verification, enumeration can be properly prevented because the case where an email address is already taken is indistinguishable from the case where it is not. However, in case of optional or disabled email verification, enumeration can only be prevented by allowing the signup to go through, resulting in multiple accounts sharing same email address (although only one of the accounts can ever have it verified). When enumeration is set to ``True``, email address uniqueness takes precedence over enumeration prevention, and the issue of multiple accounts having the same email address will be avoided, thus leaking information. Set it to ``"strict"`` to allow for signups to go through. ``ACCOUNT_RATE_LIMITS`` (default: ``{...}``) In order to be secure out of the box various rate limits are in place. See :doc:`Rate Limits <./rate_limits>` for details. ``ACCOUNT_REAUTHENTICATION_TIMEOUT`` (default: ``300``) Before asking the user to reauthenticate, we check if a successful (re)authentication happened within the amount of seconds specified here, and if that is the case, the new reauthentication flow is silently skipped. ``ACCOUNT_REAUTHENTICATION_REQUIRED`` (default: ``False``) Specifies whether or not reauthentication is required before the user can alter his account. ``ACCOUNT_SESSION_REMEMBER`` (default: ``None``) Controls the life time of the session. Set to ``None`` to ask the user ("Remember me?"), ``False`` to not remember, and ``True`` to always remember. ``ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE`` (default: ``False``) When signing up, let the user type in their email address twice to avoid typo's. ``ACCOUNT_SIGNUP_FORM_CLASS`` (default: ``None``) A string pointing to a custom form class (e.g. ``'myapp.forms.SignupForm'``) that is used during signup to ask the user for additional input (e.g. newsletter signup, birth date). This class should implement a ``def signup(self, request, user)`` method, where user represents the newly signed up user. ``ACCOUNT_SIGNUP_FORM_HONEYPOT_FIELD`` (default: ``None``) A string value that will be used as the HTML 'name' property on a honeypot input field on the sign up form. Honeypot fields are hidden to normal users but might be filled out by naive spam bots. When the field is filled out the app will not create a new user and attempt to fool the bot with a fake successful response. We recommend setting this to some believable value that your app does not actually collect on signup e.g. 'phone_number' or 'address'. Honeypots are not always successful for sophisticated bots so this should be used as one layer in a suite of spam detection tools if your site is having trouble with spam. ``ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE`` (default: ``True``) When signing up, let the user type in their password twice to avoid typos. ``ACCOUNT_SIGNUP_REDIRECT_URL`` (default: ``settings.LOGIN_REDIRECT_URL``) The URL (or URL name) to redirect to directly after signing up. Note that users are only redirected to this URL if the signup went through uninterruptedly, for example, without any side steps due to email verification. If your project requires the user to always pass through certain onboarding views after signup, you will have to keep track of state indicating whether or not the user successfully onboarded, and handle accordingly. ``ACCOUNT_TEMPLATE_EXTENSION`` (default: ``"html"``) A string defining the template extension to use, defaults to ``html``. ``ACCOUNT_USERNAME_BLACKLIST`` (default: ``[]``) A list of usernames that can't be used by user. ``ACCOUNT_UNIQUE_EMAIL`` (default: ``True``) Enforce uniqueness of email addresses. On the database level, this implies that only one user account can have an email address marked as verified. Forms prevent a user from registering with or adding an additional email address if that email address is in use by another account. ``ACCOUNT_USER_DISPLAY`` (default: a callable returning ``user.username``) A callable (or string of the form ``'some.module.callable_name'``) that takes a user as its only argument and returns the display name of the user. The default implementation returns ``user.username``. ``ACCOUNT_USER_MODEL_EMAIL_FIELD`` (default: ``"email"``) The name of the field containing the ``email``, if any. See custom user models. ``ACCOUNT_USER_MODEL_USERNAME_FIELD`` (default: ``"username"``) The name of the field containing the ``username``, if any. See custom user models. ``ACCOUNT_USERNAME_MIN_LENGTH`` (default: ``1``) An integer specifying the minimum allowed length of a username. ``ACCOUNT_USERNAME_REQUIRED`` (default: ``True``) The user is required to enter a username when signing up. Note that the user will be asked to do so even if ``ACCOUNT_AUTHENTICATION_METHOD`` is set to ``email``. Set to ``False`` when you do not wish to prompt the user to enter a username. ``ACCOUNT_USERNAME_VALIDATORS`` (default: ``None``) A path (``'some.module.validators.custom_username_validators'``) to a list of custom username validators. If left unset, the validators setup within the user model username field are used. Example:: # In validators.py from django.contrib.auth.validators import ASCIIUsernameValidator custom_username_validators = [ASCIIUsernameValidator()] # In settings.py ACCOUNT_USERNAME_VALIDATORS = 'some.module.validators.custom_username_validators' django-allauth-65.0.2/docs/account/decorators.rst000066400000000000000000000014111467545753200220000ustar00rootroot00000000000000Decorators ========== Verified Email Required ------------------------ Even when email verification is not mandatory during signup, there may be circumstances during which you really want to prevent unverified users from proceeding. For this purpose you can use the following decorator:: from allauth.account.decorators import verified_email_required @verified_email_required def verified_users_only_view(request): ... The behavior is as follows: - If the user isn't logged in, it acts identically to the ``login_required`` decorator. - If the user is logged in but has no verified email address, an email verification mail is automatically resent and the user is presented with a page informing them they need to verify their email address. django-allauth-65.0.2/docs/account/email.rst000066400000000000000000000036411467545753200207310ustar00rootroot00000000000000Email ===== Case Sensitivity **************** Historically, email addresses started out as case sensitive because the local part (the part before the "@") could represent a case sensitive user name. However, over time, this proved to be a bad idea and the RFCs that succeeded the original were adjusted to move away from treating email addresses as case sensitive. - `RFC 821 `_: The original RFC from 1982 relies on case sensitivity. - `RFC 2821 `_: Released in 2001, obsoletes RFC 821, yet, is still case sensitive. - `RFC 5321 `_: In 2008, the "Local-part" is weakened to "MAY be case-sensitive". - `RFC 6530 `_: In 2012, the following is acknowledged: It has long been the case that the email syntax permits choices about mailbox names that are **unwise in practice** [...]. The most often cited examples involve the use of **case-sensitivity** [...] in mailbox local parts. These deliberately unusual constructions **are permitted** by the protocols, and servers are expected to support them. Although they can provide value in special cases, taking advantage of them **is almost always bad practice** unless the intent is to create some form of **security by obscurity**. To deal with this, previous versions of django-allauth used to store email addresses in their original case, while performing lookups in a case insensitive style. This approach led to subtle bugs in upstream code, and also comes at a performance cost (``__iexact`` lookups). The latter requires case insensitive index support, which not all databases support. Re-evaluating the approach in current times has led to the conclusion that the benefits do not outweigh the costs. Therefore, email addresses are now always stored as lower case. django-allauth-65.0.2/docs/account/forms.rst000066400000000000000000000121741467545753200207710ustar00rootroot00000000000000Forms ===== Login ***** *Path*: ``allauth.account.forms.LoginForm`` *Used on*: `account_login `__ view. Example override:: from allauth.account.forms import LoginForm class MyCustomLoginForm(LoginForm): def login(self, *args, **kwargs): # Add your own processing here. # You must return the original result. return super(MyCustomLoginForm, self).login(*args, **kwargs) You have access to the following: - ``self.user`` is the User object that is logging in. ``settings.py``:: ACCOUNT_FORMS = {'login': 'mysite.forms.MyCustomLoginForm'} Signup ****** *Path*: ``allauth.account.forms.SignupForm`` *Used on*: `account_signup `__ view. Example override:: from allauth.account.forms import SignupForm class MyCustomSignupForm(SignupForm): def save(self, request): # Ensure you call the parent class's save. # .save() returns a User object. user = super(MyCustomSignupForm, self).save(request) # Add your own processing here. # You must return the original result. return user ``settings.py``:: ACCOUNT_FORMS = {'signup': 'mysite.forms.MyCustomSignupForm'} Add Email ********* *Path*: ``allauth.account.forms.AddEmailForm`` *Used on*: `account_email `__ view. Example override:: from allauth.account.forms import AddEmailForm class MyCustomAddEmailForm(AddEmailForm): def save(self, request): # Ensure you call the parent class's save. # .save() returns an allauth.account.models.EmailAddress object. email_address_obj = super(MyCustomAddEmailForm, self).save(request) # Add your own processing here. # You must return the original result. return email_address_obj You have access to the following: - ``self.user`` is the User object that is logged in. ``settings.py``:: ACCOUNT_FORMS = {'add_email': 'mysite.forms.MyCustomAddEmailForm'} Change Password *************** *Path*: ``allauth.account.forms.ChangePasswordForm`` *Used on*: `account_change_password `__ view. Example override:: from allauth.account.forms import ChangePasswordForm class MyCustomChangePasswordForm(ChangePasswordForm): def save(self): # Ensure you call the parent class's save. # .save() does not return anything super(MyCustomChangePasswordForm, self).save() # Add your own processing here. You have access to the following: - ``self.user`` is the User object that is logged in. ``settings.py``:: ACCOUNT_FORMS = {'change_password': 'mysite.forms.MyCustomChangePasswordForm'} Set Password ************ *Path*: ``allauth.account.forms.SetPasswordForm`` *Used on*: `account_set_password `__ view. Example override:: from allauth.account.forms import SetPasswordForm class MyCustomSetPasswordForm(SetPasswordForm): def save(self): # Ensure you call the parent class's save. # .save() does not return anything super(MyCustomSetPasswordForm, self).save() # Add your own processing here. You have access to the following: - ``self.user`` is the User object that is logged in. ``settings.py``:: ACCOUNT_FORMS = {'set_password': 'mysite.forms.MyCustomSetPasswordForm'} Reset Password ************** *Path*: ``allauth.account.forms.ResetPasswordForm`` *Used on*: `account_reset_password `__ view. Example override:: from allauth.account.forms import ResetPasswordForm class MyCustomResetPasswordForm(ResetPasswordForm): def save(self, request): # Ensure you call the parent class's save. # .save() returns a string containing the email address supplied email_address = super(MyCustomResetPasswordForm, self).save(request) # Add your own processing here. # Ensure you return the original result return email_address You have access to the following: - ``self.users`` is a list of all possible User objects with matching email address. ``settings.py``:: ACCOUNT_FORMS = {'reset_password': 'mysite.forms.MyCustomResetPasswordForm'} Reset Password From Key *********************** *Path*: ``allauth.account.forms.ResetPasswordKeyForm`` *Used on*: `account_reset_password `__ view. Example override:: from allauth.account.forms import ResetPasswordKeyForm class MyCustomResetPasswordKeyForm(ResetPasswordKeyForm): def save(self): # Add your own processing here. # Ensure you call the parent class's save. # .save() does not return anything super(MyCustomResetPasswordKeyForm, self).save() You have access to the following: - ``self.user`` is the User object. ``settings.py``:: ACCOUNT_FORMS = {'reset_password_from_key': 'mysite.forms.MyCustomResetPasswordKeyForm'} django-allauth-65.0.2/docs/account/index.rst000066400000000000000000000002711467545753200207450ustar00rootroot00000000000000Regular Accounts ================ .. toctree:: introduction configuration rate_limits views templates forms decorators signals email adapter advanced django-allauth-65.0.2/docs/account/introduction.rst000066400000000000000000000011311467545753200223530ustar00rootroot00000000000000Introduction ============ A regular account is a user account, identified by an email address or username, and protected by a password. The ``allauth.account`` app is responsible for managing regular accounts. It supports: - Authentication by username or email. - Registration of new users, with custom signup form support. - Email address management: both a simple change email address flow, and more elaborate flows with multiple email addresses (adding secondary, setting a primary) is supported. - Password forgotten flow. - Changing of the password. - Email address verification flow. django-allauth-65.0.2/docs/account/rate_limits.rst000066400000000000000000000054171467545753200221610ustar00rootroot00000000000000Rate Limits =========== In order to be secure out of the box various rate limits are in place. The rate limit mechanism is backed by a Django cache. Hence, rate limiting will not work properly if you are using the `DummyCache`. When rate limits are hit the ``429.html`` template is rendered. Rate limits are consumed by triggering actions, the full list of which is documented below. Per action, the rate can be configured. The rate itself is an amount, per time unit, per either IP address, user or action-specific key. For example, requesting a password reset is an action that is both limited globally by IP address, as well as per email. Here, the email address used is the specific key. The rate limits are configured through the ``ACCOUNT_RATE_LIMITS`` setting: - Set it to ``False`` to disable all rate limits. - Set it to a dictionary, e.g. ``{"action": "your-rate-limit", ...}`` to use the default configuration but with your specific actions overriden. The following actions are available for configuration: ``"change_password"`` (default: ``"5/m/user"``) Changing the password (for already authenticated users). ``"manage_email"`` (default: ``"10/m/user"``) Email management related actions, such as add, remove, change primary. ``"reset_password"`` (default: ``"20/m/ip,5/m/key"``) Requesting a password reset. The email for which the password is to be reset is passed as the key. ``"reauthenticate"`` (default: ``"10/m/user"``) Reauthentication (for users already logged in). ``"reset_password_from_key"`` (default: ``"20/m/ip"``) Password reset (the view the password reset email links to). ``"signup"`` (default: ``"20/m/ip"``) Signups. ``"login"`` (default: ``"30/m/ip"``) Logins. ``"login_failed"`` (default: ``"10/m/ip,5/5m/key"``) Restricts the allowed number of failed login attempts. When exceeded, the user is prohibited from logging in for the remainder of the rate limit. Important: while this protects the allauth login view, it does not protect Django's admin login from being brute forced. Note that a successful login will clear this rate limit. ``"confirm_email"`` (default: ``"1/3m/key"`` (link) or ``"1/10s/key"`` (code)) Users can request email confirmation mails via the email management view, and, implicitly, when logging in with an unverified account. This rate limit prevents users from sending too many of these mails. Additional notes: Unless the rate limit is disabled or the default limits are increased, you might run intro problems if you're running unit tests that are dependant on funcionalities covered by the rate limits. For example, if you're testing the `confirm_email` functionality in your unit tests and you're testing if the verification email is sent twice after requesting it twice, only one of the emails will be sent. django-allauth-65.0.2/docs/account/signals.rst000066400000000000000000000030641467545753200213010ustar00rootroot00000000000000Signals ======= There are several signals emitted during authentication flows. You can hook to them for your own needs. - ``allauth.account.signals.user_logged_in(request, user)`` Sent when a user logs in. - ``allauth.account.signals.user_logged_out(request, user)`` Sent when a user logs out. - ``allauth.account.signals.user_signed_up(request, user)`` Sent when a user signs up for an account. This signal is typically followed by a ``user_logged_in``, unless email verification prohibits the user to log in. - ``allauth.account.signals.password_set(request, user)`` Sent when a password has been successfully set for the first time. - ``allauth.account.signals.password_changed(request, user)`` Sent when a password has been successfully changed. - ``allauth.account.signals.password_reset(request, user)`` Sent when a password has been successfully reset. - ``allauth.account.signals.email_confirmed(request, email_address)`` Sent after the email address in the db was updated and set to confirmed. - ``allauth.account.signals.email_confirmation_sent(request, confirmation, signup)`` Sent right after the email confirmation is sent. - ``allauth.account.signals.email_changed(request, user, from_email_address, to_email_address)`` Sent when a primary email address has been changed. - ``allauth.account.signals.email_added(request, user, email_address)`` Sent when a new email address has been added. - ``allauth.account.signals.email_removed(request, user, email_address)`` Sent when an email address has been deleted. django-allauth-65.0.2/docs/account/templates.rst000066400000000000000000000013461467545753200216400ustar00rootroot00000000000000Template Tags ============= Use ``user_display`` to render a user name without making assumptions on how the user is represented (e.g. render the username, or first name?):: {% load account %} {% user_display user %} Or, if you need to use in a ``{% blocktrans %}``:: {% load account %} {% user_display user as user_display %} {% blocktrans %}{{ user_display }} has logged in...{% endblocktrans %} Then, override the ``ACCOUNT_USER_DISPLAY`` setting with your project specific user display callable. If you set ``ACCOUNT_USERNAME_REQUIRED = False`` and ``ACCOUNT_USER_MODEL_USERNAME_FIELD = None``, then you can simply display the user.email with {{ user }}:: In case you forgot, your username is {{ user }}. django-allauth-65.0.2/docs/account/views.rst000066400000000000000000000057531467545753200210050ustar00rootroot00000000000000Views ===== Login ----- *URL name*: ``account_login`` Users login via the ``allauth.account.views.LoginView`` view over at ``/accounts/login/`` (URL name ``account_login``). When users attempt to login while their account is inactive (``user.is_active``) they are presented with the ``account/account_inactive.html`` template. Signup ------ *URL name*: ``account_signup`` Users sign up via the ``allauth.account.views.SignupView`` view over at ``/accounts/signup/`` (URL name ``account_signup``). Logout ------ *URL name*: ``account_logout`` The logout view (``allauth.account.views.LogoutView``) over at ``/accounts/logout/`` (URL name ``account_logout``) requests for confirmation before logging out. The user is logged out only when the confirmation is received by means of a POST request. If you are wondering why, consider what happens when a malicious user embeds the following image in a post:: For this and more background information on the subject, see: - https://code.djangoproject.com/ticket/15619 - http://stackoverflow.com/questions/3521290/logout-get-or-post If you insist on having logout on GET, then please consider adding a bit of Javascript to automatically turn a click on a logout link into a POST. As a last resort, you can set ``ACCOUNT_LOGOUT_ON_GET`` to ``True``. Password Management ------------------- Authenticated users can manage their password account using the ``allauth.account.views.PasswordSetView`` and ``allauth.account.views.PasswordChangeView`` views, over at ``/accounts/password/set/`` respectively ``/accounts/password/change/`` (URL names ``account_set_password`` and ``account_change_password`` respectively). Users are redirected between these views, according to whether or not they have setup a password (``user.has_usable_password()``). Typically, when users signup via a social provider they will not have a password set. Password Reset -------------- *URL name*: ``account_reset_password`` Users can request a password reset using the ``allauth.account.views.PasswordResetView`` view over at ``/accounts/password/reset/`` (URL name ``account_reset_password``). An email will be sent containing a reset link pointing to ``PasswordResetFromKeyView`` view. Emails Management ----------------- *URL name*: ``account_email`` Users manage the email addresses tied to their account using the ``allauth.account.views.EmailView`` view over at ``/accounts/email/`` (URL name ``account_email``). Here, users can add (and verify) email addresses, remove email addresses, and choose a new primary email address. Email Verification ------------------- Depending on the setting ``ACCOUNT_EMAIL_VERIFICATION``, a verification email is sent pointing to the ``allauth.account.views.ConfirmEmailView`` view. The setting ``ACCOUNT_CONFIRM_EMAIL_ON_GET`` determines whether users have to manually confirm the address by submitting a confirmation form, or whether the address is automatically confirmed by a mere GET request. django-allauth-65.0.2/docs/common/000077500000000000000000000000001467545753200167405ustar00rootroot00000000000000django-allauth-65.0.2/docs/common/admin.rst000066400000000000000000000017701467545753200205670ustar00rootroot00000000000000Admin ===== The Django admin site (``django.contrib.admin``) does not use Django allauth by default. Since Django admin provides a custom login view, it does not go through the normal Django allauth workflow. .. warning:: This limitation means that Django allauth features are not applied to the Django admin site: * The admin login is not protected from being brute forced (``ACCOUNT_RATE_LIMITS``). * Two-factor authentication is not enforced. * Any other custom workflow that overrides the Django allauth adapter's login method will not be applied. An easy workaround for this is to require users to login before going to the Django admin site's login page, by adding this to urls.py (note that the following would need to be applied to every instance of ``AdminSite``): .. code-block:: python from django.contrib import admin from allauth.account.decorators import secure_admin_login admin.autodiscover() admin.site.login = secure_admin_login(admin.site.login) django-allauth-65.0.2/docs/common/configuration.rst000066400000000000000000000002751467545753200223450ustar00rootroot00000000000000Configuration ============= Available settings: ``ALLAUTH_DEFAULT_AUTO_FIELD`` Can be set to configure the primary key of all models. For example: ``"hashid_field.HashidAutoField"``. django-allauth-65.0.2/docs/common/email.rst000066400000000000000000000016731467545753200205700ustar00rootroot00000000000000Sending Email ============= Emails sent (e.g. in case of password forgotten or email confirmation) can be altered by providing your own templates. Templates are named as follows:: account/email/email_confirmation_signup_subject.txt account/email/email_confirmation_signup_message.txt account/email/email_confirmation_subject.txt account/email/email_confirmation_message.txt In case you want to include an HTML representation, add an HTML template as follows:: account/email/email_confirmation_signup_message.html account/email/email_confirmation_message.html The project does not contain any HTML email templates out of the box. When you do provide these yourself, note that both the text and HTML versions of the message are sent. If this does not suit your needs, you can hook up your own custom mechanism by overriding the ``send_mail`` method of the account adapter (``allauth.account.adapter.DefaultAccountAdapter``). django-allauth-65.0.2/docs/common/https.rst000066400000000000000000000012211467545753200206300ustar00rootroot00000000000000HTTPS ===== This app currently provides no functionality for enforcing views to be HTTPS only, or switching from HTTP to HTTPS (and back) on demand. There are third party packages aimed at providing precisely this, so please use those. What is provided is the following: - The protocol to be used for generating links (e.g. password forgotten) for emails is configurable by means of the ``ACCOUNT_DEFAULT_HTTP_PROTOCOL`` setting. - Automatically switching to HTTPS is built-in for OAuth providers that require this (e.g. Amazon). However, remembering the original protocol before the switch and switching back after the login is not provided. django-allauth-65.0.2/docs/common/index.rst000066400000000000000000000002161467545753200206000ustar00rootroot00000000000000Common Functionality ==================== .. toctree:: :maxdepth: 1 configuration email templates messages admin https django-allauth-65.0.2/docs/common/messages.rst000066400000000000000000000005141467545753200213010ustar00rootroot00000000000000Messages ======== The Django messages framework (``django.contrib.messages``) is used if it is listed in ``settings.INSTALLED_APPS``. All messages (as in ``django.contrib.messages``) are configurable by overriding their respective template. If you want to disable a message, simply override the message template with a blank one. django-allauth-65.0.2/docs/common/templates.rst000066400000000000000000000203741467545753200214760ustar00rootroot00000000000000Templates ========= Introduction ------------ The templates that are offered out of the box are intentionally plain and without any styling. We do not want to pick a side in the multitudes of frontend styling options out there, and the look and feel typically should be adjusted to match the branding of your project. Therefore it is recommended that you copy all templates over to your own project and adjust them as you see fit. Having said that, over time the years the complexity of authentication grew considerably. For example, with features such as third party account providers and two-factor authentication adjusting the templates involves a lot more than just styling a ``login.html`` and a ``signup.html`` template. Therefore, a mechanism is included that allows you to adjust the look and feel of all templates by only overriding a few core templates. This approach allows you to achieve visual results fast, but is of course more limited compared to styling all templates yourself. Overriding the Built-In Templates --------------------------------- The ``allauth`` app includes all templates, and can be found in the `allauth/templates `__ directory. When ``allauth`` is part of your ``INSTALLED_APPS``, and ``"APP_DIRS": True`` is configured, Django will be able to find its templates. As ``DIRS`` is searched before ``APP_DIRS``, overriding the templates involves adding an entry to ``DIRS`` that points to your a project specific template folder, as follows:: from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [ BASE_DIR / "templates" ], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] If you copy over all templates to your ``BASE_DIR / "templates"`` it should contain these entries (a.o.): - An ``account`` folder containing the templates from the ``allauth.account`` app. - A ``socialaccount`` folder containing the templates from the ``allauth.socialaccount`` app. - A ``mfa`` folder containing the templates from the ``allauth.mfa`` app. - An ``allauth`` folder containing the overall styling templates (see the next section). Styling the Existing Templates ------------------------------ Instead of copying all templates, a mechanism is included that allows you to adjust the look and feel of all templates by only overriding a few core templates. This approach allows you to achieve visual results fast, but is of course more limited compared to styling all templates yourself. Layouts ^^^^^^^ The existing templates use two base page layouts: - The entrance layout: These are all pages where the user is in the process of authenticating, such as the login and signup pages. - The account management layout: The pages where an authenticated user can manage the account, such as changing the email address or password. You can alter these layouts by providing these templates in your own project: ========================================== =========== Template file Description ========================================== =========== allauth/layouts/base.html The overall base template. allauth/layouts/entrance.html The entrance template, extending the base template. allauth/layouts/manage.html The account management template, extending the base template. ========================================== =========== Elements ^^^^^^^^ When rendering e.g. a Bootstrap button you would typically use:: Yet, when a different CSS framework is used other class names apply, and possibly even other markup. Therefore, the built-in templates do not include the above content directly. Instead of referring to tags such `` ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/ChangePassword.js000066400000000000000000000047731467545753200275400ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { changePassword } from '../lib/allauth' import { Navigate } from 'react-router-dom' import { useUser } from '../auth' import Button from '../components/Button' export default function ChangePassword () { const hasCurrentPassword = useUser().has_usable_password const [currentPassword, setCurrentPassword] = useState('') const [newPassword, setNewPassword] = useState('') const [newPassword2, setNewPassword2] = useState('') const [newPassword2Errors, setNewPassword2Errors] = useState([]) const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { if (newPassword !== newPassword2) { setNewPassword2Errors([{ param: 'new_password2', message: 'Password does not match.' }]) return } setNewPassword2Errors([]) setResponse({ ...response, fetching: true }) changePassword({ current_password: currentPassword, new_password: newPassword }).then((resp) => { setResponse((r) => { return { ...r, content: resp } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content?.status === 200) { return } return (

    {hasCurrentPassword ? 'Change Password' : 'Set Password'}

    {hasCurrentPassword ? 'Enter your current password, followed by your new password.' : 'You currently have no password set. Enter your (new) password.'}

    {hasCurrentPassword ?
    : null}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/ConfirmLoginCode.js000066400000000000000000000026511467545753200300020ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { confirmLoginCode, Flows } from '../lib/allauth' import { Navigate } from 'react-router-dom' import Button from '../components/Button' import { useAuthStatus } from '../auth' export default function ConfirmLoginCode () { const [, authInfo] = useAuthStatus() const [code, setCode] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) confirmLoginCode(code).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content?.status === 409 || authInfo.pendingFlow?.id !== Flows.LOGIN_BY_CODE) { return } return (

    Enter Sign-In Code

    The code expires shortly, so please enter it soon.

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/Login.js000066400000000000000000000042231467545753200256660ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { login } from '../lib/allauth' import { Link } from 'react-router-dom' import { useConfig } from '../auth' import ProviderList from '../socialaccount/ProviderList' import Button from '../components/Button' import WebAuthnLoginButton from '../mfa/WebAuthnLoginButton' export default function Login () { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) const config = useConfig() const hasProviders = config.data.socialaccount?.providers?.length > 0 function submit () { setResponse({ ...response, fetching: true }) login({ email, password }).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Login

    No account? Sign up here.

    Forgot your password?
    {config.data.account.login_by_code_enabled ? Mail me a sign-in code : null} Sign in with a passkey {hasProviders ? <>

    Or use a third-party

    : null}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/Logout.js000066400000000000000000000015411467545753200260670ustar00rootroot00000000000000import { useState } from 'react' import { Navigate } from 'react-router-dom' import { logout } from '../lib/allauth' import Button from '../components/Button' export default function Logout () { const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) logout().then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content) { return } return (

    Logout

    Are you sure you want to logout?

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/Reauthenticate.js000066400000000000000000000023301467545753200275600ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { reauthenticate, Flows } from '../lib/allauth' import ReauthenticateFlow from './ReauthenticateFlow' import Button from '../components/Button' export default function Reauthenticate () { const [password, setPassword] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) reauthenticate({ password }).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Enter your password:

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/ReauthenticateFlow.js000066400000000000000000000033721467545753200304170ustar00rootroot00000000000000import { Link, useLocation } from 'react-router-dom' import { pathForFlow } from '../auth' import { Flows, AuthenticatorType } from '../lib/allauth' const flowLabels = {} flowLabels[Flows.REAUTHENTICATE] = 'Use your password' flowLabels[`${Flows.MFA_REAUTHENTICATE}:${AuthenticatorType.TOTP}`] = 'Use your authenticator app' flowLabels[`${Flows.MFA_REAUTHENTICATE}:${AuthenticatorType.RECOVERY_CODES}`] = 'Use a recovery code' flowLabels[`${Flows.MFA_REAUTHENTICATE}:${AuthenticatorType.WEBAUTHN}`] = 'Use security key' function flowsToMethods (flows) { const methods = [] flows.forEach(flow => { if (flow.id === Flows.MFA_REAUTHENTICATE) { flow.types.forEach(typ => { const id = `${flow.id}:${typ}` methods.push({ label: flowLabels[id], id, path: pathForFlow(flow, typ) }) }) } else { methods.push({ label: flowLabels[flow.id] || flow.id, id: flow.id, path: pathForFlow(flow) }) } }) return methods } export default function ReauthenticateFlow (props) { const location = useLocation() const methods = flowsToMethods(location.state.reauth.data.flows) return (

    Confirm Access

    Please reauthenticate to safeguard your account.

    {props.children} {methods.length > 1 ? <>

    Alternative Options

      {methods.filter(method => method.id !== props.method).map(method => { return (
    • {method.label}
    • ) })}
    : null}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/RequestLoginCode.js000066400000000000000000000025251467545753200300350ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { requestLoginCode } from '../lib/allauth' import { Navigate } from 'react-router-dom' import Button from '../components/Button' export default function RequestLoginCode () { const [email, setEmail] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) requestLoginCode(email).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content?.status === 401) { return } return (

    Mail me a sign-in code

    You will receive an email containing a special code for a password-free sign-in.

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/RequestPasswordReset.js000066400000000000000000000025741467545753200310030ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { requestPasswordReset } from '../lib/allauth' import { Link } from 'react-router-dom' import Button from '../components/Button' export default function RequestPasswordReset () { const [email, setEmail] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) requestPasswordReset(email).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content?.status === 200) { return (

    Reset Password

    Password reset sent.

    ) } return (

    Reset Password

    Remember your password? Back to login.

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/ResetPassword.js000066400000000000000000000045571467545753200274350ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { getPasswordReset, resetPassword } from '../lib/allauth' import { Navigate, Link, useLoaderData } from 'react-router-dom' import Button from '../components/Button' export async function loader ({ params }) { const key = params.key const resp = await getPasswordReset(key) return { key, keyResponse: resp } } export default function ResetPassword () { const { key, keyResponse } = useLoaderData() const [password1, setPassword1] = useState('') const [password2, setPassword2] = useState('') const [password2Errors, setPassword2Errors] = useState([]) const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { if (password2 !== password1) { setPassword2Errors([{ param: 'password2', message: 'Password does not match.' }]) return } setPassword2Errors([]) setResponse({ ...response, fetching: true }) resetPassword({ key, password: password1 }).then((resp) => { setResponse((r) => { return { ...r, content: resp } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if ([200, 401].includes(response.content?.status)) { return } let body if (keyResponse.status !== 200) { body = } else if (response.content?.error?.detail?.key) { body = } else { body = ( <>
    ) } return (

    Reset Password

    Remember your password? Back to login.

    {body}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/Signup.js000066400000000000000000000046301467545753200260650ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { signUp } from '../lib/allauth' import { Link } from 'react-router-dom' import { useConfig } from '../auth' import ProviderList from '../socialaccount/ProviderList' import Button from '../components/Button' export default function Signup () { const [email, setEmail] = useState('') const [password1, setPassword1] = useState('') const [password2, setPassword2] = useState('') const [password2Errors, setPassword2Errors] = useState([]) const [response, setResponse] = useState({ fetching: false, content: null }) const config = useConfig() const hasProviders = config.data.socialaccount?.providers?.length > 0 function submit () { if (password2 !== password1) { setPassword2Errors([{ param: 'password2', message: 'Password does not match.' }]) return } setPassword2Errors([]) setResponse({ ...response, fetching: true }) signUp({ email, password: password1 }).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Sign Up

    Already have an account? Login here.

    Sign up using a passkey {hasProviders ? <>

    Or use a third-party

    : null}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/VerificationEmailSent.js000066400000000000000000000002561467545753200310440ustar00rootroot00000000000000export default function VerificationEmailSent () { return (

    Confirm Email Address

    Please confirm your email address.

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/VerifyEmail.js000066400000000000000000000031701467545753200270320ustar00rootroot00000000000000import { useState } from 'react' import { useLoaderData, Navigate } from 'react-router-dom' import { getEmailVerification, verifyEmail } from '../lib/allauth' import Button from '../components/Button' export async function loader ({ params }) { const key = params.key const resp = await getEmailVerification(key) return { key, verification: resp } } export default function VerifyEmail () { const { key, verification } = useLoaderData() const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) verifyEmail(key).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if ([200, 401].includes(response.content?.status)) { return } let body = null if (verification.status === 200) { body = ( <>

    Please confirm that {verification.data.email} is an email address for user {verification.data.user.str}.

    ) } else if (!verification.data?.email) { body =

    Invalid verification link.

    } else { body =

    Unable to confirm email {verification.data.email} because it is already confirmed.

    } return (

    Confirm Email Address

    {body}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/account/VerifyEmailByCode.js000066400000000000000000000023131467545753200301160ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { Navigate } from 'react-router-dom' import { verifyEmail } from '../lib/allauth' import Button from '../components/Button' export default function VerifyEmail () { const [code, setCode] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) verifyEmail(code).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if ([200, 401].includes(response.content?.status)) { return } return (

    Confirm Email Address

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/auth/000077500000000000000000000000001467545753200235645ustar00rootroot00000000000000django-allauth-65.0.2/examples/react-spa/frontend/src/auth/AuthContext.js000066400000000000000000000025661467545753200264010ustar00rootroot00000000000000import { useEffect, createContext, useState } from 'react' import { getAuth, getConfig } from '../lib/allauth' export const AuthContext = createContext(null) function Loading () { return
    Starting...
    } function LoadingError () { return
    Loading error!
    } export function AuthContextProvider (props) { const [auth, setAuth] = useState(undefined) const [config, setConfig] = useState(undefined) useEffect(() => { function onAuthChanged (e) { setAuth(auth => { if (typeof auth === 'undefined') { console.log('Authentication status loaded') } else { console.log('Authentication status updated') } return e.detail } ) } document.addEventListener('allauth.auth.change', onAuthChanged) getAuth().then(data => setAuth(data)).catch((e) => { console.error(e) setAuth(false) }) getConfig().then(data => setConfig(data)).catch((e) => { console.error(e) }) return () => { document.removeEventListener('allauth.auth.change', onAuthChanged) } }, []) const loading = (typeof auth === 'undefined') || config?.status !== 200 return ( {loading ? : (auth === false ? : props.children)} ) } django-allauth-65.0.2/examples/react-spa/frontend/src/auth/hooks.js000066400000000000000000000066461467545753200252610ustar00rootroot00000000000000import { useContext, useRef, useState, useEffect } from 'react' import { AuthContext } from './AuthContext' export function useAuth () { return useContext(AuthContext)?.auth } export function useConfig () { return useContext(AuthContext)?.config } export function useUser () { const auth = useContext(AuthContext)?.auth return authInfo(auth).user } export function useAuthInfo () { const auth = useContext(AuthContext)?.auth return authInfo(auth) } function authInfo (auth) { const isAuthenticated = auth.status === 200 || (auth.status === 401 && auth.meta.is_authenticated) const requiresReauthentication = isAuthenticated && auth.status === 401 const pendingFlow = auth.data?.flows?.find(flow => flow.is_pending) return { isAuthenticated, requiresReauthentication, user: isAuthenticated ? auth.data.user : null, pendingFlow } } export const AuthChangeEvent = Object.freeze({ LOGGED_OUT: 'LOGGED_OUT', LOGGED_IN: 'LOGGED_IN', REAUTHENTICATED: 'REAUTHENTICATED', REAUTHENTICATION_REQUIRED: 'REAUTHENTICATION_REQUIRED', FLOW_UPDATED: 'FLOW_UPDATED' }) function determineAuthChangeEvent (fromAuth, toAuth) { let fromInfo = authInfo(fromAuth) const toInfo = authInfo(toAuth) if (toAuth.status === 410) { return AuthChangeEvent.LOGGED_OUT } // Corner case: user ID change. Treat as if we're transitioning from anonymous state. if (fromInfo.user && toInfo.user && fromInfo.user?.id !== toInfo.user?.id) { fromInfo = { isAuthenticated: false, requiresReauthentication: false, user: null } } if (!fromInfo.isAuthenticated && toInfo.isAuthenticated) { // You typically don't transition from logged out to reauthentication required. return AuthChangeEvent.LOGGED_IN } else if (fromInfo.isAuthenticated && !toInfo.isAuthenticated) { return AuthChangeEvent.LOGGED_OUT } else if (fromInfo.isAuthenticated && toInfo.isAuthenticated) { if (toInfo.requiresReauthentication) { return AuthChangeEvent.REAUTHENTICATION_REQUIRED } else if (fromInfo.requiresReauthentication) { return AuthChangeEvent.REAUTHENTICATED } else if (fromAuth.data.methods.length < toAuth.data.methods.length) { // If you do a page reload when on the reauthentication page, both fromAuth // and toAuth are authenticated, and it won't see the change when // reauthentication without this. return AuthChangeEvent.REAUTHENTICATED } } else if (!fromInfo.isAuthenticated && !toInfo.isAuthenticated) { const fromFlow = fromInfo.pendingFlow const toFlow = toInfo.pendingFlow if (toFlow?.id && fromFlow?.id !== toFlow.id) { return AuthChangeEvent.FLOW_UPDATED } } // No change. return null } export function useAuthChange () { const auth = useAuth() const ref = useRef({ prevAuth: auth, event: null, didChange: false }) const [, setForcedUpdate] = useState(0) useEffect(() => { if (ref.current.prevAuth) { ref.current.didChange = true const event = determineAuthChangeEvent(ref.current.prevAuth, auth) if (event) { ref.current.event = event setForcedUpdate(gen => gen + 1) } } ref.current.prevAuth = auth }, [auth, ref]) const didChange = ref.current.didChange if (didChange) { ref.current.didChange = false } const event = ref.current.event if (event) { ref.current.event = null } return [auth, event] } export function useAuthStatus () { const auth = useAuth() return [auth, authInfo(auth)] } django-allauth-65.0.2/examples/react-spa/frontend/src/auth/index.js000066400000000000000000000003651467545753200252350ustar00rootroot00000000000000export { AuthContextProvider } from './AuthContext' export { URLs, pathForPendingFlow, pathForFlow, AuthChangeRedirector, AuthenticatedRoute, AnonymousRoute } from './routing' export { useConfig, useAuth, useUser, useAuthStatus } from './hooks' django-allauth-65.0.2/examples/react-spa/frontend/src/auth/routing.js000066400000000000000000000067711467545753200256240ustar00rootroot00000000000000import { Navigate, useLocation } from 'react-router-dom' import { useAuthChange, AuthChangeEvent, useAuthStatus } from './hooks' import { Flows, AuthenticatorType } from '../lib/allauth' export const URLs = Object.freeze({ LOGIN_URL: '/account/login', LOGIN_REDIRECT_URL: '/dashboard', LOGOUT_REDIRECT_URL: '/' }) const flow2path = {} flow2path[Flows.LOGIN] = '/account/login' flow2path[Flows.LOGIN_BY_CODE] = '/account/login/code/confirm' flow2path[Flows.SIGNUP] = '/account/signup' flow2path[Flows.VERIFY_EMAIL] = '/account/verify-email' flow2path[Flows.PROVIDER_SIGNUP] = '/account/provider/signup' flow2path[Flows.REAUTHENTICATE] = '/account/reauthenticate' flow2path[`${Flows.MFA_AUTHENTICATE}:${AuthenticatorType.TOTP}`] = '/account/authenticate/totp' flow2path[`${Flows.MFA_AUTHENTICATE}:${AuthenticatorType.RECOVERY_CODES}`] = '/account/authenticate/recovery-codes' flow2path[`${Flows.MFA_AUTHENTICATE}:${AuthenticatorType.WEBAUTHN}`] = '/account/authenticate/webauthn' flow2path[`${Flows.MFA_REAUTHENTICATE}:${AuthenticatorType.TOTP}`] = '/account/reauthenticate/totp' flow2path[`${Flows.MFA_REAUTHENTICATE}:${AuthenticatorType.RECOVERY_CODES}`] = '/account/reauthenticate/recovery-codes' flow2path[`${Flows.MFA_REAUTHENTICATE}:${AuthenticatorType.WEBAUTHN}`] = '/account/reauthenticate/webauthn' flow2path[Flows.MFA_WEBAUTHN_SIGNUP] = '/account/signup/passkey/create' export function pathForFlow (flow, typ) { let key = flow.id if (typeof flow.types !== 'undefined') { typ = typ ?? flow.types[0] key = `${key}:${typ}` } const path = flow2path[key] ?? flow2path[flow.id] if (!path) { throw new Error(`Unknown path for flow: ${flow.id}`) } return path } export function pathForPendingFlow (auth) { const flow = auth.data.flows.find(flow => flow.is_pending) if (flow) { return pathForFlow(flow) } return null } function navigateToPendingFlow (auth) { const path = pathForPendingFlow(auth) if (path) { return } return null } export function AuthenticatedRoute ({ children }) { const location = useLocation() const [, status] = useAuthStatus() const next = `next=${encodeURIComponent(location.pathname + location.search)}` if (status.isAuthenticated) { return children } else { return } } export function AnonymousRoute ({ children }) { const [, status] = useAuthStatus() if (!status.isAuthenticated) { return children } else { return } } export function AuthChangeRedirector ({ children }) { const [auth, event] = useAuthChange() const location = useLocation() switch (event) { case AuthChangeEvent.LOGGED_OUT: return case AuthChangeEvent.LOGGED_IN: return case AuthChangeEvent.REAUTHENTICATED: { const next = new URLSearchParams(location.search).get('next') || '/' return } case AuthChangeEvent.REAUTHENTICATION_REQUIRED: { const next = `next=${encodeURIComponent(location.pathname + location.search)}` const path = pathForFlow(auth.data.flows[0]) return } case AuthChangeEvent.FLOW_UPDATED: const pendingFlow = navigateToPendingFlow(auth) if (!pendingFlow) { throw new Error() } return pendingFlow default: break } // ...stay where we are return children } django-allauth-65.0.2/examples/react-spa/frontend/src/components/000077500000000000000000000000001467545753200250105ustar00rootroot00000000000000django-allauth-65.0.2/examples/react-spa/frontend/src/components/Button.js000066400000000000000000000001751467545753200266240ustar00rootroot00000000000000export default function Button (props) { return } django-allauth-65.0.2/examples/react-spa/frontend/src/components/FormErrors.js000066400000000000000000000005631467545753200274520ustar00rootroot00000000000000export default function FormErrors (props) { if (!props.errors || !props.errors.length) { return null } const errors = props.errors.filter(error => (props.param ? error.param === props.param : error.param == null)) if (!errors.length) { return null } return
      {errors.map((e, i) =>
    • {e.message}
    • )}
    } django-allauth-65.0.2/examples/react-spa/frontend/src/index.js000066400000000000000000000002661467545753200242740ustar00rootroot00000000000000import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' const root = ReactDOM.createRoot(document.getElementById('root')) root.render( ) django-allauth-65.0.2/examples/react-spa/frontend/src/lib/000077500000000000000000000000001467545753200233715ustar00rootroot00000000000000django-allauth-65.0.2/examples/react-spa/frontend/src/lib/allauth.js000066400000000000000000000235271467545753200253720ustar00rootroot00000000000000import { getCSRFToken } from './django' const Client = Object.freeze({ APP: 'app', BROWSER: 'browser' }) const CLIENT = Client.BROWSER const BASE_URL = `/_allauth/${CLIENT}/v1` const ACCEPT_JSON = { accept: 'application/json' } export const AuthProcess = Object.freeze({ LOGIN: 'login', CONNECT: 'connect' }) export const Flows = Object.freeze({ VERIFY_EMAIL: 'verify_email', LOGIN: 'login', LOGIN_BY_CODE: 'login_by_code', SIGNUP: 'signup', PROVIDER_REDIRECT: 'provider_redirect', PROVIDER_SIGNUP: 'provider_signup', MFA_AUTHENTICATE: 'mfa_authenticate', REAUTHENTICATE: 'reauthenticate', MFA_REAUTHENTICATE: 'mfa_reauthenticate', MFA_WEBAUTHN_SIGNUP: 'mfa_signup_webauthn' }) export const URLs = Object.freeze({ // Meta CONFIG: BASE_URL + '/config', // Account management CHANGE_PASSWORD: BASE_URL + '/account/password/change', EMAIL: BASE_URL + '/account/email', PROVIDERS: BASE_URL + '/account/providers', // Account management: 2FA AUTHENTICATORS: BASE_URL + '/account/authenticators', RECOVERY_CODES: BASE_URL + '/account/authenticators/recovery-codes', TOTP_AUTHENTICATOR: BASE_URL + '/account/authenticators/totp', // Auth: Basics LOGIN: BASE_URL + '/auth/login', REQUEST_LOGIN_CODE: BASE_URL + '/auth/code/request', CONFIRM_LOGIN_CODE: BASE_URL + '/auth/code/confirm', SESSION: BASE_URL + '/auth/session', REAUTHENTICATE: BASE_URL + '/auth/reauthenticate', REQUEST_PASSWORD_RESET: BASE_URL + '/auth/password/request', RESET_PASSWORD: BASE_URL + '/auth/password/reset', SIGNUP: BASE_URL + '/auth/signup', VERIFY_EMAIL: BASE_URL + '/auth/email/verify', // Auth: 2FA MFA_AUTHENTICATE: BASE_URL + '/auth/2fa/authenticate', MFA_REAUTHENTICATE: BASE_URL + '/auth/2fa/reauthenticate', // Auth: Social PROVIDER_SIGNUP: BASE_URL + '/auth/provider/signup', REDIRECT_TO_PROVIDER: BASE_URL + '/auth/provider/redirect', PROVIDER_TOKEN: BASE_URL + '/auth/provider/token', // Auth: Sessions SESSIONS: BASE_URL + '/auth/sessions', // Auth: WebAuthn REAUTHENTICATE_WEBAUTHN: BASE_URL + '/auth/webauthn/reauthenticate', AUTHENTICATE_WEBAUTHN: BASE_URL + '/auth/webauthn/authenticate', LOGIN_WEBAUTHN: BASE_URL + '/auth/webauthn/login', SIGNUP_WEBAUTHN: BASE_URL + '/auth/webauthn/signup', WEBAUTHN_AUTHENTICATOR: BASE_URL + '/account/authenticators/webauthn' }) export const AuthenticatorType = Object.freeze({ TOTP: 'totp', RECOVERY_CODES: 'recovery_codes', WEBAUTHN: 'webauthn' }) function postForm (action, data) { const f = document.createElement('form') f.method = 'POST' f.action = action for (const key in data) { const d = document.createElement('input') d.type = 'hidden' d.name = key d.value = data[key] f.appendChild(d) } document.body.appendChild(f) f.submit() } const tokenStorage = window.sessionStorage async function request (method, path, data, headers) { const options = { method, headers: { ...ACCEPT_JSON, ...headers } } // Don't pass along authentication related headers to the config endpoint. if (path !== URLs.CONFIG) { if (CLIENT === Client.BROWSER) { options.headers['X-CSRFToken'] = getCSRFToken() } else if (CLIENT === Client.APP) { // IMPORTANT!: Do NOT use `Client.APP` in a browser context, as you will // be vulnerable to CSRF attacks. This logic is only here for // development/demonstration/testing purposes... options.headers['User-Agent'] = 'django-allauth example app' const sessionToken = tokenStorage.getItem('sessionToken') if (sessionToken) { options.headers['X-Session-Token'] = sessionToken } } } if (typeof data !== 'undefined') { options.body = JSON.stringify(data) options.headers['Content-Type'] = 'application/json' } const resp = await fetch(path, options) const msg = await resp.json() if (msg.status === 410) { tokenStorage.removeItem('sessionToken') } if (msg.meta?.session_token) { tokenStorage.setItem('sessionToken', msg.meta.session_token) } if ([401, 410].includes(msg.status) || (msg.status === 200 && msg.meta?.is_authenticated)) { const event = new CustomEvent('allauth.auth.change', { detail: msg }) document.dispatchEvent(event) } return msg } export async function login (data) { return await request('POST', URLs.LOGIN, data) } export async function reauthenticate (data) { return await request('POST', URLs.REAUTHENTICATE, data) } export async function logout () { return await request('DELETE', URLs.SESSION) } export async function signUp (data) { return await request('POST', URLs.SIGNUP, data) } export async function signUpByPasskey (data) { return await request('POST', URLs.SIGNUP_WEBAUTHN, data) } export async function providerSignup (data) { return await request('POST', URLs.PROVIDER_SIGNUP, data) } export async function getProviderAccounts () { return await request('GET', URLs.PROVIDERS) } export async function disconnectProviderAccount (providerId, accountUid) { return await request('DELETE', URLs.PROVIDERS, { provider: providerId, account: accountUid }) } export async function requestPasswordReset (email) { return await request('POST', URLs.REQUEST_PASSWORD_RESET, { email }) } export async function requestLoginCode (email) { return await request('POST', URLs.REQUEST_LOGIN_CODE, { email }) } export async function confirmLoginCode (code) { return await request('POST', URLs.CONFIRM_LOGIN_CODE, { code }) } export async function getEmailVerification (key) { return await request('GET', URLs.VERIFY_EMAIL, undefined, { 'X-Email-Verification-Key': key }) } export async function getEmailAddresses () { return await request('GET', URLs.EMAIL) } export async function getSessions () { return await request('GET', URLs.SESSIONS) } export async function endSessions (ids) { return await request('DELETE', URLs.SESSIONS, { sessions: ids }) } export async function getAuthenticators () { return await request('GET', URLs.AUTHENTICATORS) } export async function getTOTPAuthenticator () { return await request('GET', URLs.TOTP_AUTHENTICATOR) } export async function mfaAuthenticate (code) { return await request('POST', URLs.MFA_AUTHENTICATE, { code }) } export async function mfaReauthenticate (code) { return await request('POST', URLs.MFA_REAUTHENTICATE, { code }) } export async function activateTOTPAuthenticator (code) { return await request('POST', URLs.TOTP_AUTHENTICATOR, { code }) } export async function deactivateTOTPAuthenticator () { return await request('DELETE', URLs.TOTP_AUTHENTICATOR) } export async function getRecoveryCodes () { return await request('GET', URLs.RECOVERY_CODES) } export async function generateRecoveryCodes () { return await request('POST', URLs.RECOVERY_CODES) } export async function getConfig () { return await request('GET', URLs.CONFIG) } export async function addEmail (email) { return await request('POST', URLs.EMAIL, { email }) } export async function deleteEmail (email) { return await request('DELETE', URLs.EMAIL, { email }) } export async function markEmailAsPrimary (email) { return await request('PATCH', URLs.EMAIL, { email, primary: true }) } export async function requestEmailVerification (email) { return await request('PUT', URLs.EMAIL, { email }) } export async function verifyEmail (key) { return await request('POST', URLs.VERIFY_EMAIL, { key }) } export async function getPasswordReset (key) { return await request('GET', URLs.RESET_PASSWORD, undefined, { 'X-Password-Reset-Key': key }) } export async function resetPassword (data) { return await request('POST', URLs.RESET_PASSWORD, data) } export async function changePassword (data) { return await request('POST', URLs.CHANGE_PASSWORD, data) } export async function getAuth () { return await request('GET', URLs.SESSION) } export async function authenticateByToken (providerId, token, process = AuthProcess.LOGIN) { return await request('POST', URLs.PROVIDER_TOKEN, { provider: providerId, token, process } ) } export function redirectToProvider (providerId, callbackURL, process = AuthProcess.LOGIN) { postForm(URLs.REDIRECT_TO_PROVIDER, { provider: providerId, process, callback_url: callbackURL, csrfmiddlewaretoken: getCSRFToken() }) } export async function getWebAuthnCreateOptions (passwordless) { let url = URLs.WEBAUTHN_AUTHENTICATOR if (passwordless) { url += '?passwordless' } return await request('GET', url) } export async function getWebAuthnCreateOptionsAtSignup () { return await request('GET', URLs.SIGNUP_WEBAUTHN) } export async function addWebAuthnCredential (name, credential) { return await request('POST', URLs.WEBAUTHN_AUTHENTICATOR, { name, credential }) } export async function signupWebAuthnCredential (name, credential) { return await request('PUT', URLs.SIGNUP_WEBAUTHN, { name, credential }) } export async function deleteWebAuthnCredential (ids) { return await request('DELETE', URLs.WEBAUTHN_AUTHENTICATOR, { authenticators: ids }) } export async function updateWebAuthnCredential (id, data) { return await request('PUT', URLs.WEBAUTHN_AUTHENTICATOR, { id, ...data }) } export async function getWebAuthnRequestOptionsForReauthentication () { return await request('GET', URLs.REAUTHENTICATE_WEBAUTHN) } export async function reauthenticateUsingWebAuthn (credential) { return await request('POST', URLs.REAUTHENTICATE_WEBAUTHN, { credential }) } export async function authenticateUsingWebAuthn (credential) { return await request('POST', URLs.AUTHENTICATE_WEBAUTHN, { credential }) } export async function loginUsingWebAuthn (credential) { return await request('POST', URLs.LOGIN_WEBAUTHN, { credential }) } export async function getWebAuthnRequestOptionsForLogin () { return await request('GET', URLs.LOGIN_WEBAUTHN) } export async function getWebAuthnRequestOptionsForAuthentication () { return await request('GET', URLs.AUTHENTICATE_WEBAUTHN) } django-allauth-65.0.2/examples/react-spa/frontend/src/lib/django.js000066400000000000000000000010651467545753200251730ustar00rootroot00000000000000function getCookie (name) { let cookieValue = null if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';') for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim() // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)) break } } } return cookieValue } export function getCSRFToken () { return getCookie('csrftoken') } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/000077500000000000000000000000001467545753200233665ustar00rootroot00000000000000django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/ActivateTOTP.js000066400000000000000000000032521467545753200261750ustar00rootroot00000000000000import { useState } from 'react' import * as allauth from '../lib/allauth' import { Navigate, useLoaderData } from 'react-router-dom' import FormErrors from '../components/FormErrors' import Button from '../components/Button' export async function loader ({ params }) { const resp = await allauth.getTOTPAuthenticator() return { totp: resp } } export default function ActivateTOTP (props) { const { totp } = useLoaderData() const [code, setCode] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) allauth.activateTOTPAuthenticator(code).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (totp.status === 200 || response.content?.status === 200) { return } return (

    Activate TOTP

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/AddWebAuthn.js000066400000000000000000000040511467545753200260520ustar00rootroot00000000000000import { useState } from 'react' import { Navigate } from 'react-router-dom' import FormErrors from '../components/FormErrors' import Button from '../components/Button' import * as allauth from '../lib/allauth' import { create, parseCreationOptionsFromJSON } from '@github/webauthn-json/browser-ponyfill' export default function AddWebAuthn (props) { const [passwordless, setPasswordless] = useState(false) const [name, setName] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) async function submit () { setResponse({ ...response, fetching: true }) try { const optResp = await allauth.getWebAuthnCreateOptions(passwordless) if (optResp.status === 200) { const jsonOptions = optResp.data.creation_options const options = parseCreationOptionsFromJSON(jsonOptions) const credential = await create(options) const addResp = await allauth.addWebAuthnCredential(name, credential) setResponse((r) => { return { ...r, content: addResp } }) } else { setResponse((r) => { return { ...r, content: optResp } }) } } catch (e) { console.error(e) window.alert(e) } setResponse((r) => { return { ...r, fetching: false } }) } if (response.content?.status === 200) { return } return (

    Add Security Key

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/AuthenticateCode.js000066400000000000000000000024741467545753200271440ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import * as allauth from '../lib/allauth' import Button from '../components/Button' import { useAuthInfo } from '../auth/hooks' import { Navigate } from 'react-router-dom' import AuthenticateFlow from './AuthenticateFlow' export default function AuthenticateCode (props) { const [code, setCode] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) const authInfo = useAuthInfo() if (authInfo?.pendingFlow?.id !== allauth.Flows.MFA_AUTHENTICATE) { return } function submit () { setResponse({ ...response, fetching: true }) allauth.mfaAuthenticate(code).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return ( {props.children} ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/AuthenticateFlow.js000066400000000000000000000022141467545753200271710ustar00rootroot00000000000000import { Link, Navigate } from 'react-router-dom' import { pathForFlow } from '../auth' import { Flows, AuthenticatorType } from '../lib/allauth' import { useAuthInfo } from '../auth/hooks' const labels = {} labels[AuthenticatorType.TOTP] = 'Use your authenticator app' labels[AuthenticatorType.RECOVERY_CODES] = 'Use a recovery code' labels[AuthenticatorType.WEBAUTHN] = 'Use security key' export default function AuthenticateFlow (props) { const authInfo = useAuthInfo() if (authInfo?.pendingFlow?.id !== Flows.MFA_AUTHENTICATE) { return } const flow = authInfo.pendingFlow return (

    Two-Factor Authentication

    Your account is protected by two-factor authentication.

    {props.children} {flow.types.length > 1 ? <>

    Alternative Options

      {flow.types.map(typ => { return (
    • {labels[typ]}
    • ) })}
    : null}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/AuthenticateRecoveryCodes.js000066400000000000000000000005021467545753200310340ustar00rootroot00000000000000import AuthenticateCode from './AuthenticateCode' import { AuthenticatorType } from '../lib/allauth' export default function AuthenticateRecoveryCodes (props) { return (

    Please enter a recovery code:

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/AuthenticateTOTP.js000066400000000000000000000004761467545753200270600ustar00rootroot00000000000000import AuthenticateCode from './AuthenticateCode' import { AuthenticatorType } from '../lib/allauth' export default function AuthenticateRecoveryCodes (props) { return (

    Please enter an authenticator code:

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/AuthenticateWebAuthn.js000066400000000000000000000023741467545753200300060ustar00rootroot00000000000000import { useState } from 'react' import { AuthenticatorType, getWebAuthnRequestOptionsForAuthentication, authenticateUsingWebAuthn } from '../lib/allauth' import Button from '../components/Button' import { parseRequestOptionsFromJSON, get } from '@github/webauthn-json/browser-ponyfill' import AuthenticateFlow from './AuthenticateFlow' export default function AuthenticateWebAuthn (props) { const [response, setResponse] = useState({ fetching: false, content: null }) async function submit () { setResponse({ ...response, fetching: true }) try { const optResp = await getWebAuthnRequestOptionsForAuthentication() const jsonOptions = optResp.data.request_options const options = parseRequestOptionsFromJSON(jsonOptions) const credential = await get(options) const reauthResp = await authenticateUsingWebAuthn(credential) setResponse((r) => { return { ...r, content: reauthResp } }) } catch (e) { console.error(e) window.alert(e) } setResponse((r) => { return { ...r, fetching: false } }) } return ( ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/CreateSignupPasskey.js000066400000000000000000000040501467545753200276540ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { Flows } from '../lib/allauth' import { Navigate } from 'react-router-dom' import Button from '../components/Button' import { useAuthStatus } from '../auth' import * as allauth from '../lib/allauth' import { create, parseCreationOptionsFromJSON } from '@github/webauthn-json/browser-ponyfill' export default function CreateSignupPasskey () { const [, authInfo] = useAuthStatus() const [name, setName] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) async function submit () { setResponse({ ...response, fetching: true }) try { const optResp = await allauth.getWebAuthnCreateOptionsAtSignup(true) if (optResp.status === 200) { const jsonOptions = optResp.data.creation_options const options = parseCreationOptionsFromJSON(jsonOptions) const credential = await create(options) const signupResp = await allauth.signupWebAuthnCredential(name, credential) setResponse((r) => { return { ...r, content: signupResp } }) } else { setResponse((r) => { return { ...r, content: optResp } }) } } catch (e) { console.error(e) window.alert(e) } setResponse((r) => { return { ...r, fetching: false } }) } if (response.content?.status === 409 || authInfo.pendingFlow?.id !== Flows.MFA_WEBAUTHN_SIGNUP) { return } return (

    Create Passkey

    You are about to create a passkey for your account. As you can add additional keys later on, you can use a descriptive name to tell the keys apart.

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/DeactivateTOTP.js000066400000000000000000000017171467545753200265120ustar00rootroot00000000000000import { useState } from 'react' import * as allauth from '../lib/allauth' import { Navigate } from 'react-router-dom' import Button from '../components/Button' export default function DeactivateTOTP (props) { const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) allauth.deactivateTOTPAuthenticator().then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content?.status === 200) { return } return (

    Deactivate Authenticator App

    You are about to deactivate authenticator app based authentication. Are you sure?

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/GenerateRecoveryCodes.js000066400000000000000000000026461467545753200301630ustar00rootroot00000000000000import { useState } from 'react' import { Navigate, useLoaderData } from 'react-router-dom' import FormErrors from '../components/FormErrors' import Button from '../components/Button' import * as allauth from '../lib/allauth' export async function loader ({ params }) { const resp = await allauth.getRecoveryCodes() return { recoveryCodes: resp } } export default function GenerateRecoveryCodes () { const { recoveryCodes } = useLoaderData() const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) allauth.generateRecoveryCodes().then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } if (response.content?.status === 200) { return } const hasCodes = recoveryCodes.status === 200 && recoveryCodes.data.unused_code_count > 0 return (

    Recovery Codes

    You are about to generate a new set of recovery codes for your account. {hasCodes ? 'This action will invalidate your existing codes.' : ''} Are you sure?

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/ListWebAuthn.js000066400000000000000000000071131467545753200262770ustar00rootroot00000000000000import { useState } from 'react' import { Link, useLoaderData, Navigate } from 'react-router-dom' import Button from '../components/Button' import * as allauth from '../lib/allauth' export async function loader ({ params }) { const resp = await allauth.getAuthenticators() return { authenticators: resp.data } } function Authenticator (props) { const [name, setName] = useState(props.authenticator.name) const { authenticator } = props function onSubmit (e) { e.preventDefault() props.onSave(name) } return ( {props.editting ? setName(e.target.value)} value={name} type='text' /> : {authenticator.name} } {typeof authenticator.is_passwordless === 'undefined' ? 'Type unspecified' : (authenticator.is_passwordless ? 'Passkey' : 'Security key')} {new Date(authenticator.created_at * 1000).toLocaleString()} {authenticator.last_used_at ? new Date(authenticator.last_used_at * 1000).toLocaleString() : 'Unused'} ) } export default function ListWebAuthn (props) { const { authenticators } = useLoaderData() const [editId, setEditId] = useState(null) const [keys, setKeys] = useState(() => authenticators.filter(authenticator => authenticator.type === allauth.AuthenticatorType.WEBAUTHN)) const [response, setResponse] = useState({ fetching: false, content: null }) async function optimisticSetKeys (newKeys, op) { setResponse({ ...response, fetching: true }) const oldKeys = keys setEditId(null) setKeys(newKeys) try { const ok = await op() if (!ok) { setKeys(oldKeys) } } catch (e) { setKeys(oldKeys) console.error(e) window.alert(e) } setResponse((r) => { return { ...r, fetching: false } }) } async function deleteKey (key) { const newKeys = keys.filter((k) => k.id !== key.id) await optimisticSetKeys(newKeys, async () => { const resp = await allauth.deleteWebAuthnCredential([key.id]) return (resp.status === 200) }) } async function onSave (key, name) { const newKeys = keys.filter((k) => k.id !== key.id) newKeys.push({ ...key, name }) await optimisticSetKeys(newKeys, async () => { const resp = await allauth.updateWebAuthnCredential(key.id, { name }) return (resp.status === 200) }) } if (!keys.length && !response.fetching) { return } return (

    Security Keys

    {keys.map(key => { return ( setEditId(null)} onSave={(name) => onSave(key, name)} onEdit={() => setEditId(key.id)} onDelete={() => deleteKey(key)} /> ) })}
    Name Type Created At Last Used At Actions
    Add
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/MFAOverview.js000066400000000000000000000035521467545753200260630ustar00rootroot00000000000000import { Link, useLoaderData } from 'react-router-dom' import * as allauth from '../lib/allauth' export async function loader ({ params }) { const resp = await allauth.getAuthenticators() return { authenticators: resp.data } } export default function MFAOverview (props) { const { authenticators } = useLoaderData() const totp = authenticators.find(authenticator => authenticator.type === allauth.AuthenticatorType.TOTP) const webauthn = authenticators.filter(authenticator => authenticator.type === allauth.AuthenticatorType.WEBAUTHN) const recoveryCodes = authenticators.find(authenticator => authenticator.type === allauth.AuthenticatorType.RECOVERY_CODES) return (

    Two-Factor Authentication

    Authenticator App

    {totp ? <>

    Authentication using an authenticator app is active.

    Deactivate : <>

    An authenticator app is not active..

    Activate }

    Security Keys

    {webauthn.length ? <>

    You have added {webauthn.length} security keys.

    Manage : <>

    No security keys have been added.

    Add }

    Recovery Codes

    {!recoveryCodes ? <>

    No recovery codes set up.

    Generate : <>

    There are {recoveryCodes.unused_code_count} out of {recoveryCodes.total_code_count} recovery codes available.

    View Regenerate }
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/ReauthenticateCode.js000066400000000000000000000022361467545753200274670ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { mfaReauthenticate } from '../lib/allauth' import ReauthenticateFlow from '../account/ReauthenticateFlow' import Button from '../components/Button' export default function ReauthenticateCode (props) { const [code, setCode] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) mfaReauthenticate(code).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return ( {props.children}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/ReauthenticateRecoveryCodes.js000066400000000000000000000003441467545753200313670ustar00rootroot00000000000000import ReauthenticateCode from './ReauthenticateCode' export default function ReauthenticateRecoveryCodes (props) { return (

    Please enter a recovery code:

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/ReauthenticateTOTP.js000066400000000000000000000003411467545753200273760ustar00rootroot00000000000000import ReauthenticateCode from './ReauthenticateCode' export default function ReauthenticateTOTP (props) { return (

    Please enter an authenticator code:

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/ReauthenticateWebAuthn.js000066400000000000000000000023701467545753200303310ustar00rootroot00000000000000import { useState } from 'react' import { Flows, getWebAuthnRequestOptionsForReauthentication, reauthenticateUsingWebAuthn } from '../lib/allauth' import ReauthenticateFlow from '../account/ReauthenticateFlow' import Button from '../components/Button' import { parseRequestOptionsFromJSON, get } from '@github/webauthn-json/browser-ponyfill' export default function ReauthenticateWebAuthn () { const [response, setResponse] = useState({ fetching: false, content: null }) async function submit () { setResponse({ ...response, fetching: true }) try { const optResp = await getWebAuthnRequestOptionsForReauthentication() const jsonOptions = optResp.data.request_options const options = parseRequestOptionsFromJSON(jsonOptions) const credential = await get(options) const reauthResp = await reauthenticateUsingWebAuthn(credential) setResponse((r) => { return { ...r, content: reauthResp } }) } catch (e) { console.error(e) window.alert(e) } setResponse((r) => { return { ...r, fetching: false } }) } return ( ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/RecoveryCodes.js000066400000000000000000000013011467545753200264730ustar00rootroot00000000000000import { useLoaderData } from 'react-router-dom' import * as allauth from '../lib/allauth' export async function loader ({ params }) { const resp = await allauth.getRecoveryCodes() return { recoveryCodes: resp } } export default function RecoveryCodes (props) { const { recoveryCodes } = useLoaderData() return (

    Recovery Codes

    {recoveryCodes.status === 200 ? <>

    There are {recoveryCodes.data.unused_code_count} out of {recoveryCodes.data.total_code_count} recovery codes available.

    {recoveryCodes.data.unused_codes.join('\n')}
    : <>

    No recovery codes set up.

    }
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/SignupByPasskey.js000066400000000000000000000024101467545753200270210ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { signUpByPasskey } from '../lib/allauth' import { Link } from 'react-router-dom' import Button from '../components/Button' export default function Signup () { const [email, setEmail] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) signUpByPasskey({ email }).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Passkey Sign Up

    Already have an account? Login here.

    Sign up using a password
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/mfa/WebAuthnLoginButton.js000066400000000000000000000020341467545753200276250ustar00rootroot00000000000000import Button from '../components/Button' import { useState } from 'react' import { getWebAuthnRequestOptionsForLogin, loginUsingWebAuthn } from '../lib/allauth' import { parseRequestOptionsFromJSON, get } from '@github/webauthn-json/browser-ponyfill' export default function WebAuthnLoginButton (props) { const [response, setResponse] = useState({ fetching: false, content: null }) async function submit (e) { e.preventDefault() setResponse({ ...response, fetching: true }) try { const optResp = await getWebAuthnRequestOptionsForLogin() const jsonOptions = optResp.data.request_options const options = parseRequestOptionsFromJSON(jsonOptions) const credential = await get(options) const loginResp = await loginUsingWebAuthn(credential) setResponse((r) => { return { ...r, content: loginResp } }) } catch (e) { console.error(e) window.alert(e) } setResponse((r) => { return { ...r, fetching: false } }) } return } django-allauth-65.0.2/examples/react-spa/frontend/src/socialaccount/000077500000000000000000000000001467545753200254525ustar00rootroot00000000000000django-allauth-65.0.2/examples/react-spa/frontend/src/socialaccount/GoogleOneTap.js000066400000000000000000000033721467545753200303400ustar00rootroot00000000000000import { useState } from 'react' import { useConfig } from '../auth' import { authenticateByToken } from '../lib/allauth' function installGoogleOneTap (cb) { const id = 'google-one-tap' const scr = document.getElementById(id) if (!scr) { const scr = document.createElement('script') scr.id = id scr.src = '//accounts.google.com/gsi/client' scr.async = true scr.addEventListener('load', function () { cb() }) document.body.appendChild(scr) } else { cb() } } export default function GoogleOneTap (props) { const config = useConfig() const [enabled, setEnabled] = useState(() => window.sessionStorage.getItem('googleOneTapEnabled') === 'yes') function onGoogleOneTapInstalled () { const provider = config.data.socialaccount.providers.find(p => p.id === 'google') if (provider && window.google) { function handleCredentialResponse (token) { authenticateByToken(provider.id, { id_token: token.credential, client_id: provider.client_id }, props.process) } window.google.accounts.id.initialize({ client_id: provider.client_id, callback: handleCredentialResponse }) window.google.accounts.id.prompt() } } if (enabled) { installGoogleOneTap(onGoogleOneTapInstalled) return null } function enable () { window.sessionStorage.setItem('googleOneTapEnabled', 'yes') installGoogleOneTap(onGoogleOneTapInstalled) setEnabled(true) } return (
    Mind your privacy: Do you want to demo Google One Tap sign-in?
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/socialaccount/ManageProviders.js000066400000000000000000000040511467545753200310760ustar00rootroot00000000000000import { useState, useEffect } from 'react' import * as allauth from '../lib/allauth' import ProviderList from './ProviderList' import FormErrors from '../components/FormErrors' import Button from '../components/Button' export default function ManageProviders () { const [accounts, setAccounts] = useState([]) const [response, setResponse] = useState({ fetching: false, content: { status: 200, data: [] } }) useEffect(() => { setResponse((r) => { return { ...r, fetching: true } }) allauth.getProviderAccounts().then((resp) => { if (resp.status === 200) { setAccounts(resp.data) } }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) }, []) function disconnect (account) { setResponse({ ...response, fetching: true }) allauth.disconnectProviderAccount(account.provider.id, account.uid).then((resp) => { setResponse((r) => { return { ...r, content: resp } }) if (resp.status === 200) { setAccounts(resp.data) } }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Providers

    {accounts.map(account => { return ( ) })}
    UID Account Provider Actions
    {account.uid} {account.display} {account.provider.name}

    Connect

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/socialaccount/ProviderCallback.js000066400000000000000000000012671467545753200312250ustar00rootroot00000000000000import { Navigate, useLocation, Link } from 'react-router-dom' import { URLs, pathForPendingFlow, useAuthStatus } from '../auth' export default function ProviderCallback () { const location = useLocation() const params = new URLSearchParams(location.search) const error = params.get('error') const [auth, status] = useAuthStatus() let url = URLs.LOGIN_URL if (status.isAuthenticated) { url = URLs.LOGIN_REDIRECT_URL } else { url = pathForPendingFlow(auth) || url } if (!error) { return } return ( <>

    Third-Party Login Failure

    Something went wrong.

    Continue ) } django-allauth-65.0.2/examples/react-spa/frontend/src/socialaccount/ProviderList.js000066400000000000000000000013141467545753200304350ustar00rootroot00000000000000import { useConfig } from '../auth' import { redirectToProvider } from '../lib/allauth' import Button from '../components/Button' import GoogleOneTap from './GoogleOneTap' export default function ProviderList (props) { const config = useConfig() const providers = config.data.socialaccount.providers if (!providers.length) { return null } return ( <>
      {providers.map(provider => { return (
    • ) })}
    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/socialaccount/ProviderSignup.js000066400000000000000000000023111467545753200307650ustar00rootroot00000000000000import { useState } from 'react' import FormErrors from '../components/FormErrors' import { providerSignup } from '../lib/allauth' import { Link } from 'react-router-dom' import Button from '../components/Button' export default function ProviderSignup () { const [email, setEmail] = useState('') const [response, setResponse] = useState({ fetching: false, content: null }) function submit () { setResponse({ ...response, fetching: true }) providerSignup({ email }).then((content) => { setResponse((r) => { return { ...r, content } }) }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Sign Up

    Already have an account? Login here.

    ) } django-allauth-65.0.2/examples/react-spa/frontend/src/usersessions/000077500000000000000000000000001467545753200253705ustar00rootroot00000000000000django-allauth-65.0.2/examples/react-spa/frontend/src/usersessions/Sessions.js000066400000000000000000000043321467545753200275360ustar00rootroot00000000000000import { useState, useEffect } from 'react' import { useConfig } from '../auth' import * as allauth from '../lib/allauth' import Button from '../components/Button' export default function Sessions () { const config = useConfig() const [sessions, setSessions] = useState([]) const [response, setResponse] = useState({ fetching: false, content: { status: 200, data: [] } }) useEffect(() => { setResponse((r) => { return { ...r, fetching: true } }) allauth.getSessions().then((resp) => { if (resp.status === 200) { setSessions(resp.data) } }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) }, []) const otherSessions = sessions.filter(session => !session.is_current) function logout (sessions) { setResponse({ ...response, fetching: true }) allauth.endSessions(sessions.map(s => s.id)).then((resp) => { setResponse((r) => { return { ...r, content: resp } }) if (resp.status === 200) { setSessions(resp.data) } }).catch((e) => { console.error(e) window.alert(e) }).then(() => { setResponse((r) => { return { ...r, fetching: false } }) }) } return (

    Sessions

    {config.data.usersessions.track_activity ? : null} {sessions.map((session, i) => { return ( {config.data.usersessions.track_activity ? : null} ) })}
    Started At IP Address BrowserLast Seen AtCurrent Actions
    {new Date(session.created_at).toLocaleString()} {session.ip} {session.user_agent}{session.last_seen_at}{session.is_current ? '⭐' : ''}
    ) } django-allauth-65.0.2/examples/react-spa/traefik.toml000066400000000000000000000013401467545753200225350ustar00rootroot00000000000000defaultEntryPoints = ["http"] [log] level = "DEBUG" [api] dashboard = true [accessLog] [providers] providersThrottleDuration = 10 [providers.file] filename = "traefik.toml" directory = "/etc/traefik/" watch = true [entryPoints] [entryPoints.web] address = ":10000" [http.routers] [http.routers.django] service = "django" rule = "PathPrefix(`/accounts`) || PathPrefix(`/_allauth`)" entrypoints = ["web"] [http.routers.react] service = "react" rule = "PathPrefix(`/`)" entrypoints = ["web"] [http.services] [http.services.react.loadBalancer] [[http.services.react.loadBalancer.servers]] url = "http://frontend:3000" [http.services.django.loadBalancer] [[http.services.django.loadBalancer.servers]] url = "http://backend:8000" django-allauth-65.0.2/examples/regular-django/000077500000000000000000000000001467545753200212375ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/.dockerignore000066400000000000000000000001251467545753200237110ustar00rootroot00000000000000.git .cache tmp/ bak/ **/__pycache__ *~ .pytest_cache .vagrant build/ .pytest_cache/ django-allauth-65.0.2/examples/regular-django/Dockerfile000066400000000000000000000004651467545753200232360ustar00rootroot00000000000000FROM python:3.12 ENV PYTHONUNBUFFERED 1 # Needed for SAML support RUN apt-get update RUN apt-get -y install libxml2-dev libxmlsec1-dev libxmlsec1-openssl WORKDIR /code/ COPY requirements.txt \ manage.py \ Makefile \ ./ RUN pip install -r requirements.txt COPY ./example ./example/ EXPOSE 8000 django-allauth-65.0.2/examples/regular-django/Makefile000066400000000000000000000003411467545753200226750ustar00rootroot00000000000000ifeq ($(wildcard /code),) PYTHON=PYTHONPATH=$$PYTHONPATH:../.. python3 else PYTHON=python3 endif MANAGE_PY=$(PYTHON) manage.py .PHONY: migrate: $(MANAGE_PY) migrate .PHONY: runserver: $(MANAGE_PY) runserver 0.0.0.0:8000 django-allauth-65.0.2/examples/regular-django/README.org000066400000000000000000000020311467545753200227010ustar00rootroot00000000000000* Regular Django Example Application ** Run using Docker #+begin_src sh docker-compose up #+end_src You should then be able to open your browser on http://localhost:8000 and see a page with links to sign in or sign up. ** Run Locally Assuming you use virtualenv, follow these steps to download and run the django-allauth example application in this directory: #+begin_src sh git clone git@codeberg.org:allauth/django-allauth.git cd django-allauth/examples/regular-django virtualenv venv . venv/bin/activate pip install "../..[mfa,saml,socialaccount]" #+end_src Now we need to create the database tables and an admin user. Run the following and when prompted to create a superuser choose yes and follow the instructions: #+begin_src sh python manage.py migrate python manage.py createsuperuser #+end_src Finally, run the Django development server: #+begin_src sh python manage.py runserver #+end_src You should then be able to open your browser on http://localhost:8000 and see a page with links to sign in or sign up. django-allauth-65.0.2/examples/regular-django/db/000077500000000000000000000000001467545753200216245ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/db/.gitignore000066400000000000000000000000131467545753200236060ustar00rootroot00000000000000example.db django-allauth-65.0.2/examples/regular-django/docker-compose.yml000066400000000000000000000005211467545753200246720ustar00rootroot00000000000000version: "3" services: web: build: context: ./ dockerfile: Dockerfile volumes: - ./example:/code/example/ - ../../allauth:/code/allauth - ./db:/srv/db environment: DATABASE_NAME: /srv/db/example.db ports: - 8000:8000 command: - make - migrate - runserver django-allauth-65.0.2/examples/regular-django/example/000077500000000000000000000000001467545753200226725ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/__init__.py000066400000000000000000000000001467545753200247710ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/asgi.py000066400000000000000000000002511467545753200241650ustar00rootroot00000000000000import os from django.core.asgi import get_asgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings") application = get_asgi_application() django-allauth-65.0.2/examples/regular-django/example/demo/000077500000000000000000000000001467545753200236165ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/demo/__init__.py000066400000000000000000000000001467545753200257150ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/demo/apps.py000066400000000000000000000003451467545753200251350ustar00rootroot00000000000000from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ class DemoConfig(AppConfig): name = "example.demo" verbose_name = _("Demo") default_auto_field = "django.db.models.AutoField" django-allauth-65.0.2/examples/regular-django/example/demo/models.py000066400000000000000000000000001467545753200254410ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/demo/tests.py000066400000000000000000000005771467545753200253430ustar00rootroot00000000000000""" This file demonstrates writing tests using the unittest module. These will pass when you run "manage.py test". Replace this with more appropriate tests for your application. """ from django.test import TestCase class SimpleTest(TestCase): def test_basic_addition(self): """ Tests that 1 + 1 always equals 2. """ self.assertEqual(1 + 1, 2) django-allauth-65.0.2/examples/regular-django/example/demo/views.py000066400000000000000000000000321467545753200253200ustar00rootroot00000000000000# Create your views here. django-allauth-65.0.2/examples/regular-django/example/settings.py000066400000000000000000000167021467545753200251120ustar00rootroot00000000000000# Django settings for example project. import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent DEBUG = True ADMINS = ( # ('Your Name', 'your_email@example.com'), ) MANAGERS = ADMINS EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", # Add 'postgresql_psycopg2', 'postgresql', # 'mysql', 'sqlite3' or 'oracle'. "NAME": os.environ.get( "DATABASE_NAME", os.path.join(BASE_DIR / "db" / "example.db") ), "USER": "", # Not used with sqlite3. "PASSWORD": "", # Not used with sqlite3. "HOST": "", # Set to empty string for localhost. Not used with sqlite3. "PORT": "", # Set to empty string for default. Not used with sqlite3. } } # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # On Unix systems, a value of None will cause Django to use the same # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = "America/Chicago" # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = "en" LANGUAGES = [ ("ar", "Arabic"), ("az", "Azerbaijani"), ("bg", "Bulgarian"), ("ca", "Catalan"), ("cs", "Czech"), ("da", "Danish"), ("de", "German"), ("el", "Greek"), ("en", "English"), ("es", "Spanish"), ("et", "Estonian"), ("eu", "Basque"), ("fa", "Persian"), ("fi", "Finnish"), ("fr", "French"), ("he", "Hebrew"), ("hr", "Croatian"), ("hu", "Hungarian"), ("id", "Indonesian"), ("it", "Italian"), ("ja", "Japanese"), ("ka", "Georgian"), ("ko", "Korean"), ("ky", "Kyrgyz"), ("lt", "Lithuanian"), ("lv", "Latvian"), ("mn", "Mongolian"), ("nb", "Norwegian Bokmål"), ("nl", "Dutch"), ("pl", "Polish"), ("pt-BR", "Portuguese (Brazil)"), ("pt-PT", "Portuguese (Portugal)"), ("ro", "Romanian"), ("ru", "Russian"), ("sk", "Slovak"), ("sl", "Slovenian"), ("sr", "Serbian"), ("sr-Latn", "Serbian (Latin)"), ("sv", "Swedish"), ("th", "Thai"), ("tr", "Turkish"), ("uk", "Ukrainian"), ("zh-hans", "Chinese (Simplified)"), ("zh-hant", "Chinese (Traditional)"), ] SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale USE_L10N = True # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = "" # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = "" # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = "" # URL prefix for static files. # Example: "http://media.lawrence.com/static/" STATIC_URL = "/static/" # Additional locations of static files STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. ) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", # 'django.contrib.staticfiles.finders.DefaultStorageFinder', ) # Make this unique, and don't share it with anybody. SECRET_KEY = "t8_)kj3v!au0!_i56#gre**mkg0&z1df%3bw(#5^#^5e_64!$_" # List of callables that know how to import templates from various sources. TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [ BASE_DIR / "example" / "templates", ], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] MIDDLEWARE = ( "django.middleware.common.CommonMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.middleware.locale.LocaleMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "allauth.account.middleware.AccountMiddleware", ) AUTHENTICATION_BACKENDS = ("allauth.account.auth_backends.AuthenticationBackend",) ROOT_URLCONF = "example.urls" INSTALLED_APPS = ( "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.humanize", "django.contrib.sites", "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.admin", "allauth", "allauth.account", "allauth.socialaccount", "allauth.mfa", "allauth.socialaccount.providers.dropbox", "allauth.socialaccount.providers.dingtalk", "allauth.socialaccount.providers.facebook", "allauth.socialaccount.providers.edx", "allauth.socialaccount.providers.evernote", "allauth.socialaccount.providers.google", "allauth.socialaccount.providers.github", "allauth.socialaccount.providers.linkedin_oauth2", "allauth.socialaccount.providers.mediawiki", "allauth.socialaccount.providers.openid", "allauth.socialaccount.providers.openid_connect", "allauth.socialaccount.providers.pinterest", "allauth.socialaccount.providers.pocket", "allauth.socialaccount.providers.reddit", "allauth.socialaccount.providers.saml", "allauth.socialaccount.providers.shopify", "allauth.socialaccount.providers.slack", "allauth.socialaccount.providers.snapchat", "allauth.socialaccount.providers.soundcloud", "allauth.socialaccount.providers.stackexchange", "allauth.socialaccount.providers.telegram", "allauth.socialaccount.providers.twitch", "allauth.socialaccount.providers.twitter", "allauth.socialaccount.providers.twitter_oauth2", "allauth.socialaccount.providers.vimeo", "allauth.socialaccount.providers.vimeo_oauth2", "allauth.socialaccount.providers.weibo", "allauth.socialaccount.providers.xing", "allauth.usersessions", "example.demo", ) AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", "OPTIONS": { "min_length": 9, }, } ] ALLOWED_HOSTS = ["127.0.0.1", "localhost"] SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") ACCOUNT_LOGIN_BY_CODE_ENABLED = True MFA_SUPPORTED_TYPES = [ "webauthn", "totp", "recovery_codes", ] MFA_PASSKEY_LOGIN_ENABLED = True MFA_PASSKEY_SIGNUP_ENABLED = True try: from .local_settings import * # noqa except ImportError: pass django-allauth-65.0.2/examples/regular-django/example/templates/000077500000000000000000000000001467545753200246705ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/429.html000066400000000000000000000004451467545753200260770ustar00rootroot00000000000000{% extends "allauth/layouts/entrance.html" %} {% load allauth %} {% block head_title %} Too Many Requests {% endblock head_title %} {% block content %} {% element h1 %} Too Many Requests {% endelement %}

    You are sending too many requests.

    {% endblock content %} django-allauth-65.0.2/examples/regular-django/example/templates/account/000077500000000000000000000000001467545753200263245ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/account/base_manage_email.html000066400000000000000000000001561467545753200326050ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} {% block nav_class_email %}{{ block.super }} active{% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/account/base_manage_password.html000066400000000000000000000001611467545753200333540ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} {% block nav_class_password %}{{ block.super }} active{% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/000077500000000000000000000000001467545753200263225ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/000077500000000000000000000000001467545753200301365ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/alert.html000066400000000000000000000002541467545753200321340ustar00rootroot00000000000000{% load allauth %}
    {% slot message %} {% endslot %}
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/badge.html000066400000000000000000000007261467545753200320730ustar00rootroot00000000000000{% load allauth %} {% setvar variant %} {% if "warning" in attrs.tags %} warning {% elif "danger" in attrs.tags %} danger {% elif "secondary" in attrs.tags %} secondary {% elif "success" in attrs.tags %} success {% else %} primary {% endif %} {% endsetvar %} {% slot %} {% endslot %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/button.html000066400000000000000000000042221467545753200323370ustar00rootroot00000000000000{% load allauth %} {% comment %} djlint:off {% endcomment %} <{% if attrs.href %}a href="{{ attrs.href }}"{% else %}button{% endif %} {% if attrs.form %}form="{{ attrs.form }}"{% endif %} {% if attrs.id %}id="{{ attrs.id }}"{% endif %} {% if attrs.name %}name="{{ attrs.name }}"{% endif %} {% if attrs.type %}type="{{ attrs.type }}"{% endif %} {% if attrs.value %}value="{{ attrs.value }}"{% endif %} class="{% block class %} btn {% if "link" in attrs.tags %}btn-link {% else %} {% if "prominent" in attrs.tags %}btn-lg{% elif "minor" in attrs.tags %}btn-sm{% endif %} btn-{% if 'outline' in attrs.tags %}outline-{% endif %}{% if "danger" in attrs.tags %}danger{% elif "secondary" in attrs.tags %}secondary{% elif "warning" in attrs.tags %}warning{% else %}primary{% endif %} {% endif %}{% endblock %}"> {% if "tool" in attrs.tags %} {% if "delete" in attrs.tags %} {% elif "edit" in attrs.tags %} {% endif %} {% endif %} {% if not "tool" in attrs.tags %} {% slot %} {% endslot %} {% endif %} button__entrance.html000066400000000000000000000002011467545753200342670ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements{% extends "allauth/elements/button.html" %} {% load allauth %} {% block class %} {{ block.super }} w-100 {% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/button_group.html000066400000000000000000000001571467545753200335560ustar00rootroot00000000000000{% load allauth %}
    {% slot %} {% endslot %}
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/field.html000066400000000000000000000064001467545753200321070ustar00rootroot00000000000000{% load allauth %} {% if attrs.type == "checkbox" or attrs.type == "radio" %}
    {% if slots.help_text %}
    {% slot help_text %} {% endslot %}
    {% endif %}
    {% elif attrs.type == "textarea" %}
    {% elif attrs.type == "hidden" %} {% else %}
    {% if not attrs.unlabeled %} {% endif %} {% if attrs.unlabeled %} {% endif %} {% if slots.help_text %}
    {% slot help_text %} {% endslot %}
    {% endif %} {% if attrs.errors %} {% for error in attrs.errors %}
    {{ error }}
    {% endfor %} {% endif %}
    {% endif %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/fields.html000066400000000000000000000012671467545753200323000ustar00rootroot00000000000000{% load allauth %} {% for bound_field in attrs.form %} {% element field unlabeled=attrs.unlabeled name=bound_field.name type=bound_field.field.widget.input_type required=bound_field.field.required value=bound_field.value id=bound_field.auto_id errors=bound_field.errors placeholder=bound_field.field.widget.attrs.placeholder tabindex=bound_field.field.widget.attrs.tabindex autocomplete=bound_field.field.widget.attrs.autocomplete style=bound_field.field.widget.attrs.style %} {% slot label %} {{ bound_field.label }} {% endslot %} {% slot help_text %} {{ bound_field.field.help_text }} {% endslot %} {% endelement %} {% endfor %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/form.html000066400000000000000000000012411467545753200317650ustar00rootroot00000000000000{% load allauth %} {% for err in attrs.form.non_field_errors %}
    {{ err }}
    {% endfor %}
    {% if not attrs.no_visible_fields %}
    {% endif %} {% slot body %} {% endslot %} {% if not attrs.no_visible_fields %}
    {% endif %} {% if not attrs.no_visible_fields %}{% endif %}
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/form__entrance.html000066400000000000000000000001201467545753200337760ustar00rootroot00000000000000{% extends "allauth/elements/form.html" %} {% block form_class %}{% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/h1.html000066400000000000000000000001141467545753200313300ustar00rootroot00000000000000{% load allauth %}

    {% slot %} {% endslot %}

    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/h1__entrance.html000066400000000000000000000001241467545753200333470ustar00rootroot00000000000000{% load allauth %}

    {% slot %} {% endslot %}

    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/h2__entrance.html000066400000000000000000000001241467545753200333500ustar00rootroot00000000000000{% load allauth %}

    {% slot %} {% endslot %}

    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/img.html000066400000000000000000000002301467545753200315730ustar00rootroot00000000000000
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/panel.html000066400000000000000000000006011467545753200321200ustar00rootroot00000000000000{% load allauth %}
    {% slot title %} {% endslot %}
    {% slot body %} {% endslot %}
    {% if slots.actions %} {% endif %}
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/provider.html000066400000000000000000000001721467545753200326560ustar00rootroot00000000000000{% load allauth %} {{ attrs.name }} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/provider_list.html000066400000000000000000000001241467545753200337060ustar00rootroot00000000000000{% load allauth %}
    {% slot %} {% endslot %}
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/elements/table.html000066400000000000000000000001411467545753200321070ustar00rootroot00000000000000{% load allauth %} {% slot %} {% endslot %}
    django-allauth-65.0.2/examples/regular-django/example/templates/allauth/layouts/000077500000000000000000000000001467545753200300225ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/allauth/layouts/base.html000066400000000000000000000113301467545753200316200ustar00rootroot00000000000000 {% load i18n %} {% block head_title %}{% endblock %}
    {% block body %} {% block content %} {% endblock content %} {% endblock body %} {% block extra_body %} {% endblock extra_body %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/layouts/entrance.html000066400000000000000000000020371467545753200325110ustar00rootroot00000000000000{% extends "allauth/layouts/base.html" %} {% load i18n allauth %} {% block body %}
    {% if messages %} {% for message in messages %} {% element alert level=message.tags %} {% slot message %} {{ message }} {% endslot %} {% endelement %} {% endfor %} {% endif %}
    {% block content %}{% endblock %}
    {% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/allauth/layouts/manage.html000066400000000000000000000054211467545753200321420ustar00rootroot00000000000000{% extends "allauth/layouts/base.html" %} {% load allauth %} {% block body %}
    {% if messages %}
    {% for message in messages %} {% element alert level=message.tags %} {% slot message %} {{ message }} {% endslot %} {% endelement %} {% endfor %}
    {% endif %} {% block content %}{% endblock %}
    {% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/index.html000066400000000000000000000003501467545753200266630ustar00rootroot00000000000000{% extends "allauth/layouts/entrance.html" %} {% load allauth %} {% block content %} {% element h1 %} Example Project {% endelement %}

    Welcome to the django-allauth example project.

    {% endblock content %} django-allauth-65.0.2/examples/regular-django/example/templates/mfa/000077500000000000000000000000001467545753200254335ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/mfa/base_manage.html000066400000000000000000000001541467545753200305430ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} {% block nav_class_mfa %}{{ block.super }} active{% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/profile.html000066400000000000000000000002741467545753200272210ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} {% load allauth %} {% block content %} {% element h1 %} Profile {% endelement %}

    Your profile

    {% endblock content %} django-allauth-65.0.2/examples/regular-django/example/templates/socialaccount/000077500000000000000000000000001467545753200275175ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/socialaccount/base_manage.html000066400000000000000000000001661467545753200326320ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} {% block nav_class_socialaccount %}{{ block.super }} active{% endblock %} django-allauth-65.0.2/examples/regular-django/example/templates/usersessions/000077500000000000000000000000001467545753200274355ustar00rootroot00000000000000django-allauth-65.0.2/examples/regular-django/example/templates/usersessions/base_manage.html000066400000000000000000000001651467545753200325470ustar00rootroot00000000000000{% extends "allauth/layouts/manage.html" %} {% block nav_class_usersessions %}{{ block.super }} active{% endblock %} django-allauth-65.0.2/examples/regular-django/example/urls.py000066400000000000000000000010641467545753200242320ustar00rootroot00000000000000from django.contrib import admin from django.urls import include, path from django.views.generic.base import TemplateView from allauth.account.decorators import secure_admin_login admin.autodiscover() admin.site.login = secure_admin_login(admin.site.login) urlpatterns = [ path("", TemplateView.as_view(template_name="index.html")), path("accounts/", include("allauth.urls")), path("accounts/profile/", TemplateView.as_view(template_name="profile.html")), path("admin/", admin.site.urls), path("i18n/", include("django.conf.urls.i18n")), ] django-allauth-65.0.2/examples/regular-django/example/wsgi.py000066400000000000000000000002511467545753200242130ustar00rootroot00000000000000import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings") application = get_wsgi_application() django-allauth-65.0.2/examples/regular-django/manage.py000066400000000000000000000003731467545753200230440ustar00rootroot00000000000000#!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) django-allauth-65.0.2/examples/regular-django/requirements.txt000066400000000000000000000000651467545753200245240ustar00rootroot00000000000000django-allauth[mfa,saml,socialaccount,steam]>=65.0.2 django-allauth-65.0.2/manage.py000066400000000000000000000003451467545753200163240ustar00rootroot00000000000000#!/usr/bin/env python import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.regular.settings") from django.core import management # noqa: E402 if __name__ == "__main__": management.execute_from_command_line() django-allauth-65.0.2/package-lock.json000066400000000000000000004150711467545753200177440ustar00rootroot00000000000000{ "name": "django-allauth", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "django-allauth", "license": "ISC", "devDependencies": { "standard": "^17.1.0" } }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/@babel/code-frame": { "version": "7.8.3", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@babel/highlight": "^7.8.3" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.9.5", "dev": true, "license": "MIT", "peer": true }, "node_modules/@babel/highlight": { "version": "7.9.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.9.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint-community/regexpp": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@eslint/js": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "engines": { "node": ">=12.22" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { "node": ">= 8" } }, "node_modules/@types/color-name": { "version": "1.1.1", "dev": true, "license": "MIT", "peer": true }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, "node_modules/acorn": { "version": "7.1.1", "dev": true, "license": "MIT", "peer": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-escapes": { "version": "4.3.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "type-fest": "^0.11.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-escapes/node_modules/type-fest": { "version": "0.11.0", "dev": true, "license": "(MIT OR CC0-1.0)", "peer": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "3.2.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/argparse": { "version": "1.0.10", "dev": true, "license": "MIT", "peer": true, "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-includes": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.filter": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "es-array-method-boxes-properly": "^1.0.0", "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.findlast": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz", "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", "es-abstract": "^1.22.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.findlastindex": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", "es-abstract": "^1.22.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.flatmap": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.toreversed": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, "node_modules/array.prototype.tosorted": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", "es-abstract": "^1.22.3", "es-errors": "^1.1.0", "es-shim-unscopables": "^1.0.2" } }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", "define-properties": "^1.2.1", "es-abstract": "^1.22.3", "es-errors": "^1.2.1", "get-intrinsic": "^1.2.3", "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/astral-regex": { "version": "1.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=4" } }, "node_modules/asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", "dev": true, "dependencies": { "has-symbols": "^1.0.3" } }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/balanced-match": { "version": "1.0.0", "dev": true, "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, "dependencies": { "semver": "^7.0.0" } }, "node_modules/builtins/node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { "version": "3.1.0", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/chalk": { "version": "2.4.2", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/chardet": { "version": "0.7.0", "dev": true, "license": "MIT", "peer": true }, "node_modules/cli-cursor": { "version": "3.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "restore-cursor": "^3.1.0" }, "engines": { "node": ">=8" } }, "node_modules/cli-width": { "version": "2.2.1", "dev": true, "license": "ISC", "peer": true }, "node_modules/color-convert": { "version": "1.9.3", "dev": true, "license": "MIT", "peer": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "dev": true, "license": "MIT", "peer": true }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "6.0.5", "dev": true, "license": "MIT", "peer": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" }, "engines": { "node": ">=4.8" } }, "node_modules/cross-spawn/node_modules/semver": { "version": "5.7.1", "dev": true, "license": "ISC", "peer": true, "bin": { "semver": "bin/semver" } }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/deep-is": { "version": "0.1.3", "dev": true, "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/doctrine": { "version": "3.0.0", "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=6.0.0" } }, "node_modules/emoji-regex": { "version": "8.0.0", "dev": true, "license": "MIT", "peer": true }, "node_modules/error-ex": { "version": "1.3.2", "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { "version": "1.22.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "hasown": "^2.0.1", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", "safe-array-concat": "^1.1.0", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.8", "string.prototype.trimend": "^1.0.7", "string.prototype.trimstart": "^1.0.7", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", "typed-array-length": "^1.0.5", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-array-method-boxes-properly": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", "dev": true }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, "dependencies": { "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "engines": { "node": ">= 0.4" } }, "node_modules/es-iterator-helpers": { "version": "1.0.17", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", "dev": true, "dependencies": { "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.22.4", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.2", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", "iterator.prototype": "^1.1.2", "safe-array-concat": "^1.1.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/escape-string-regexp": { "version": "1.0.5", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { "version": "6.8.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "ajv": "^6.10.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", "eslint-utils": "^1.4.3", "eslint-visitor-keys": "^1.1.0", "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.14", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.3", "progress": "^2.0.0", "regexpp": "^2.0.1", "semver": "^6.1.2", "strip-ansi": "^5.2.0", "strip-json-comments": "^3.0.1", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { "debug": "^3.2.7" }, "engines": { "node": ">=4" }, "peerDependenciesMeta": { "eslint": { "optional": true } } }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.8.0", "hasown": "^2.0.0", "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.7", "object.groupby": "^1.0.1", "object.values": "^1.1.7", "semver": "^6.3.1", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-plugin-react": { "version": "7.34.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz", "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==", "dev": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlast": "^1.2.4", "array.prototype.flatmap": "^1.3.2", "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.0.17", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.7", "object.fromentries": "^2.0.7", "object.hasown": "^1.1.3", "object.values": "^1.1.7", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.10" }, "engines": { "node": ">=4" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/eslint-plugin-react/node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/eslint-plugin-react/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-scope": { "version": "5.0.0", "dev": true, "license": "BSD-2-Clause", "peer": true, "dependencies": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" }, "engines": { "node": ">=8.0.0" } }, "node_modules/eslint-utils": { "version": "1.4.3", "dev": true, "license": "MIT", "peer": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" } }, "node_modules/eslint-visitor-keys": { "version": "1.1.0", "dev": true, "license": "Apache-2.0", "peer": true, "engines": { "node": ">=4" } }, "node_modules/espree": { "version": "6.2.1", "dev": true, "license": "BSD-2-Clause", "peer": true, "dependencies": { "acorn": "^7.1.1", "acorn-jsx": "^5.2.0", "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/esprima": { "version": "4.0.1", "dev": true, "license": "BSD-2-Clause", "peer": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esquery/node_modules/estraverse": { "version": "5.1.0", "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", "dev": true, "license": "BSD-2-Clause", "peer": true, "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/external-editor": { "version": "3.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" }, "engines": { "node": ">=4" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "dev": true, "license": "MIT" }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" } }, "node_modules/figures": { "version": "3.2.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/file-entry-cache": { "version": "5.0.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "flat-cache": "^2.0.1" }, "engines": { "node": ">=4" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-up/node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/flat-cache": { "version": "2.0.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" }, "engines": { "node": ">=4" } }, "node_modules/flatted": { "version": "2.0.2", "dev": true, "license": "ISC", "peer": true }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/fs.realpath": { "version": "1.0.0", "dev": true, "license": "ISC" }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/functional-red-black-tree": { "version": "1.0.1", "dev": true, "license": "MIT", "peer": true }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-stdin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/glob": { "version": "7.1.6", "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "5.1.1", "dev": true, "license": "ISC", "peer": true, "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/globals": { "version": "12.4.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "type-fest": "^0.8.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, "dependencies": { "define-properties": "^1.1.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.2.4", "dev": true, "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { "version": "3.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=4" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasown": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dev": true, "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/iconv-lite": { "version": "0.4.24", "dev": true, "license": "MIT", "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ignore": { "version": "4.0.6", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.2.1", "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" } }, "node_modules/imurmurhash": { "version": "0.1.4", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "dev": true, "license": "ISC" }, "node_modules/inquirer": { "version": "7.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.15", "mute-stream": "0.0.8", "run-async": "^2.4.0", "rxjs": "^6.5.3", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "engines": { "node": ">=6.0.0" } }, "node_modules/inquirer/node_modules/ansi-styles": { "version": "4.2.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/inquirer/node_modules/chalk": { "version": "3.0.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/color-convert": { "version": "2.0.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/inquirer/node_modules/color-name": { "version": "1.1.4", "dev": true, "license": "MIT", "peer": true }, "node_modules/inquirer/node_modules/has-flag": { "version": "4.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/strip-ansi": { "version": "6.0.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-regex": "^5.0.0" }, "engines": { "node": ">=8" } }, "node_modules/inquirer/node_modules/supports-color": { "version": "7.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { "node": ">= 0.4" } }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { "version": "0.2.1", "dev": true, "license": "MIT" }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { "version": "2.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-finalizationregistry": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dev": true, "dependencies": { "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=8" } }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-set": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakset": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, "node_modules/isexe": { "version": "2.0.0", "dev": true, "license": "ISC" }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", "dev": true, "dependencies": { "define-properties": "^1.2.1", "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", "reflect.getprototypeof": "^1.0.4", "set-function-name": "^2.0.1" } }, "node_modules/js-tokens": { "version": "4.0.0", "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "3.13.1", "dev": true, "license": "MIT", "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, "license": "MIT" }, "node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" }, "engines": { "node": ">=4.0" } }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/levn": { "version": "0.3.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { "version": "4.17.15", "dev": true, "license": "MIT", "peer": true }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/mimic-fn": { "version": "2.1.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=6" } }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/mkdirp": { "version": "0.5.5", "dev": true, "license": "MIT", "peer": true, "dependencies": { "minimist": "^1.2.5" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/ms": { "version": "2.1.2", "dev": true, "license": "MIT" }, "node_modules/mute-stream": { "version": "0.0.8", "dev": true, "license": "ISC", "peer": true }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, "license": "MIT" }, "node_modules/nice-try": { "version": "1.0.5", "dev": true, "license": "MIT", "peer": true }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.entries": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.groupby": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", "dev": true, "dependencies": { "array.prototype.filter": "^1.0.3", "call-bind": "^1.0.5", "define-properties": "^1.2.1", "es-abstract": "^1.22.3", "es-errors": "^1.0.0" } }, "node_modules/object.hasown": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", "dev": true, "dependencies": { "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/once": { "version": "1.4.0", "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "mimic-fn": "^2.1.0" }, "engines": { "node": ">=6" } }, "node_modules/optionator": { "version": "0.8.3", "dev": true, "license": "MIT", "peer": true, "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/os-tmpdir": { "version": "1.0.2", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parent-module": { "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/path-exists": { "version": "3.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "2.0.1", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=4" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/pkg-conf": { "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { "find-up": "^3.0.0", "load-json-file": "^5.2.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/find-up": { "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { "locate-path": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/load-json-file": { "version": "5.3.0", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.1.15", "parse-json": "^4.0.0", "pify": "^4.0.1", "strip-bom": "^3.0.0", "type-fest": "^0.3.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/locate-path": { "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/p-limit": { "version": "2.3.0", "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pkg-conf/node_modules/p-locate": { "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/p-try": { "version": "2.2.0", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/parse-json": { "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" }, "engines": { "node": ">=4" } }, "node_modules/pkg-conf/node_modules/pify": { "version": "4.0.1", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pkg-conf/node_modules/type-fest": { "version": "0.3.1", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=6" } }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, "engines": { "node": ">= 0.4" } }, "node_modules/prelude-ls": { "version": "1.1.2", "dev": true, "peer": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/progress": { "version": "2.0.3", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=0.4.0" } }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "node_modules/punycode": { "version": "2.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "node_modules/reflect.getprototypeof": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", "es-abstract": "^1.22.3", "es-errors": "^1.0.0", "get-intrinsic": "^1.2.3", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { "version": "2.0.1", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=6.5.0" } }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { "version": "4.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/restore-cursor": { "version": "3.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { "node": ">=8" } }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { "version": "2.6.3", "dev": true, "license": "ISC", "peer": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "node_modules/run-async": { "version": "2.4.1", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=0.12.0" } }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rxjs": { "version": "6.5.5", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { "tslib": "^1.9.0" }, "engines": { "npm": ">=2.0.0" } }, "node_modules/safe-array-concat": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", "dev": true, "dependencies": { "call-bind": "^1.0.5", "get-intrinsic": "^1.2.2", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, "engines": { "node": ">=0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safer-buffer": { "version": "2.1.2", "dev": true, "license": "MIT", "peer": true }, "node_modules/semver": { "version": "6.3.0", "dev": true, "license": "ISC", "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/set-function-length": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", "dev": true, "dependencies": { "define-data-property": "^1.1.2", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/set-function-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/shebang-command": { "version": "1.2.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "shebang-regex": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/shebang-regex": { "version": "1.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", "object-inspect": "^1.13.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { "version": "3.0.3", "dev": true, "license": "ISC", "peer": true }, "node_modules/slice-ansi": { "version": "2.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=4" } }, "node_modules/sprintf-js": { "version": "1.0.3", "dev": true, "license": "BSD-3-Clause", "peer": true }, "node_modules/standard": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/standard/-/standard-17.1.0.tgz", "integrity": "sha512-jaDqlNSzLtWYW4lvQmU0EnxWMUGQiwHasZl5ZEIwx3S/ijZDjZOzs1y1QqKwKs5vqnFpGtizo4NOYX2s0Voq/g==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "eslint": "^8.41.0", "eslint-config-standard": "17.1.0", "eslint-config-standard-jsx": "^11.0.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-n": "^15.7.0", "eslint-plugin-promise": "^6.1.1", "eslint-plugin-react": "^7.32.2", "standard-engine": "^15.0.0", "version-guard": "^1.1.1" }, "bin": { "standard": "bin/cmd.cjs" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/standard-engine": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-15.1.0.tgz", "integrity": "sha512-VHysfoyxFu/ukT+9v49d4BRXIokFRZuH3z1VRxzFArZdjSCFpro6rEIU3ji7e4AoAtuSfKBkiOmsrDqKW5ZSRw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "get-stdin": "^8.0.0", "minimist": "^1.2.6", "pkg-conf": "^3.1.0", "xdg-basedir": "^4.0.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/standard/node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/standard/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/standard/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "node_modules/standard/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/standard/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/standard/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/standard/node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/standard/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/standard/node_modules/eslint": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.0", "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/standard/node_modules/eslint-config-standard": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "engines": { "node": ">=12.0.0" }, "peerDependencies": { "eslint": "^8.0.1", "eslint-plugin-import": "^2.25.2", "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", "eslint-plugin-promise": "^6.0.0" } }, "node_modules/standard/node_modules/eslint-config-standard-jsx": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz", "integrity": "sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "peerDependencies": { "eslint": "^8.8.0", "eslint-plugin-react": "^7.28.0" } }, "node_modules/standard/node_modules/eslint-plugin-es": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", "dev": true, "dependencies": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" }, "engines": { "node": ">=8.10.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { "eslint": ">=4.19.1" } }, "node_modules/standard/node_modules/eslint-plugin-es/node_modules/eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/standard/node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/standard/node_modules/eslint-plugin-n": { "version": "15.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz", "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==", "dev": true, "dependencies": { "builtins": "^5.0.1", "eslint-plugin-es": "^4.1.0", "eslint-utils": "^3.0.0", "ignore": "^5.1.1", "is-core-module": "^2.11.0", "minimatch": "^3.1.2", "resolve": "^1.22.1", "semver": "^7.3.8" }, "engines": { "node": ">=12.22.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { "eslint": ">=7.0.0" } }, "node_modules/standard/node_modules/eslint-plugin-promise": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/standard/node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/standard/node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { "eslint": ">=5" } }, "node_modules/standard/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/standard/node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/standard/node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/standard/node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/standard/node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/standard/node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/standard/node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/standard/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { "is-glob": "^4.0.3" }, "engines": { "node": ">=10.13.0" } }, "node_modules/standard/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/standard/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/standard/node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/standard/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/standard/node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/standard/node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/standard/node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/standard/node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/standard/node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/standard/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/standard/node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/standard/node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/standard/node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/standard/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/standard/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/standard/node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/standard/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/standard/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/string-width": { "version": "4.2.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, "node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-regex": "^5.0.0" }, "engines": { "node": ">=8" } }, "node_modules/string.prototype.matchall": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", "regexp.prototype.flags": "^1.5.0", "set-function-name": "^2.0.0", "side-channel": "^1.0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trim": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimend": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { "version": "5.2.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } }, "node_modules/strip-ansi/node_modules/ansi-regex": { "version": "4.1.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=6" } }, "node_modules/strip-bom": { "version": "3.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/table": { "version": "5.4.6", "dev": true, "license": "BSD-3-Clause", "peer": true, "dependencies": { "ajv": "^6.10.2", "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/table/node_modules/emoji-regex": { "version": "7.0.3", "dev": true, "license": "MIT", "peer": true }, "node_modules/table/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=4" } }, "node_modules/table/node_modules/string-width": { "version": "3.1.0", "dev": true, "license": "MIT", "peer": true, "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" }, "engines": { "node": ">=6" } }, "node_modules/text-table": { "version": "0.2.0", "dev": true, "license": "MIT" }, "node_modules/through": { "version": "2.3.8", "dev": true, "license": "MIT", "peer": true }, "node_modules/tmp": { "version": "0.0.33", "dev": true, "license": "MIT", "peer": true, "dependencies": { "os-tmpdir": "~1.0.2" }, "engines": { "node": ">=0.6.0" } }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tslib": { "version": "1.11.2", "dev": true, "license": "0BSD", "peer": true }, "node_modules/type-check": { "version": "0.3.2", "dev": true, "license": "MIT", "peer": true, "dependencies": { "prelude-ls": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/type-fest": { "version": "0.8.1", "dev": true, "license": "(MIT OR CC0-1.0)", "peer": true, "engines": { "node": ">=8" } }, "node_modules/typed-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-proto": "^1.0.3", "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typed-array-byte-offset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-proto": "^1.0.3", "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typed-array-length": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/uri-js": { "version": "4.2.2", "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/v8-compile-cache": { "version": "2.1.0", "dev": true, "license": "MIT", "peer": true }, "node_modules/version-guard": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/version-guard/-/version-guard-1.1.1.tgz", "integrity": "sha512-MGQLX89UxmYHgDvcXyjBI0cbmoW+t/dANDppNPrno64rYr8nH4SHSuElQuSYdXGEs0mUzdQe1BY+FhVPNsAmJQ==", "dev": true, "engines": { "node": ">=0.10.48" } }, "node_modules/which": { "version": "1.3.1", "dev": true, "license": "ISC", "peer": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", "dev": true, "dependencies": { "function.prototype.name": "^1.1.5", "has-tostringtag": "^1.0.0", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", "is-finalizationregistry": "^1.0.2", "is-generator-function": "^1.0.10", "is-regex": "^1.1.4", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.0.2", "which-collection": "^1.0.1", "which-typed-array": "^1.1.9" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-collection": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "dev": true, "dependencies": { "is-map": "^2.0.1", "is-set": "^2.0.1", "is-weakmap": "^2.0.1", "is-weakset": "^2.0.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.6", "call-bind": "^1.0.5", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/word-wrap": { "version": "1.2.3", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/wrappy": { "version": "1.0.2", "dev": true, "license": "ISC" }, "node_modules/write": { "version": "1.0.3", "dev": true, "license": "MIT", "peer": true, "dependencies": { "mkdirp": "^0.5.1" }, "engines": { "node": ">=4" } }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } } } django-allauth-65.0.2/package.json000066400000000000000000000003071467545753200170060ustar00rootroot00000000000000{ "name": "django-allauth", "devDependencies": { "standard": "^17.1.0" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } django-allauth-65.0.2/pyproject.toml000066400000000000000000000001311467545753200174270ustar00rootroot00000000000000[build-system] requires = ['setuptools>=40.8.0'] build-backend = 'setuptools.build_meta' django-allauth-65.0.2/pytest.ini000066400000000000000000000001461467545753200165520ustar00rootroot00000000000000[pytest] DJANGO_SETTINGS_MODULE = tests.regular.settings python_files = tests.py test_*.py *_tests.py django-allauth-65.0.2/setup.cfg000066400000000000000000000050551467545753200163460ustar00rootroot00000000000000[metadata] name = django-allauth version = attr: allauth.__version__ url = https://allauth.org author = Raymond Penners author_email = raymond.penners@intenct.nl description = Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication. long_description = file: README.rst long_description_content_type = text/x-rst license = MIT classifiers = Development Status :: 5 - Production/Stable Intended Audience :: Developers Topic :: Software Development :: Libraries :: Python Modules Environment :: Web Environment Topic :: Internet License :: OSI Approved :: MIT License Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 Framework :: Django Framework :: Django :: 4.2 Framework :: Django :: 5.0 Framework :: Django :: 5.1 project_urls = Documentation = https://docs.allauth.org/en/latest/ Changelog = https://codeberg.org/allauth/django-allauth/src/branch/main/ChangeLog.rst Source = https://codeberg.org/allauth/django-allauth Tracker = https://codeberg.org/allauth/django-allauth/issues Donate = https://github.com/sponsors/pennersr [options] python_requires = >=3.8 packages = find: include_package_data = true zip_safe = false tests_require = Pillow >= 9.0 pytest >= 7.4 pytest-asyncio == 0.23.8 pytest-django >= 4.5.2 install_requires = Django >= 4.2 [options.extras_require] mfa = qrcode >= 7.0.0 fido2 >= 1.1.2 openid = python3-openid >= 3.0.8 saml = python3-saml>=1.15.0,<2.0.0 steam = python3-openid >= 3.0.8 socialaccount = requests-oauthlib >= 0.3.0 requests >= 2.0.0 pyjwt[crypto] >= 1.7 [options.packages.find] exclude = examples tests tests.* [isort] indent=4 combine_star=1 combine_as_imports=1 include_trailing_comma=1 multi_line_output=3 lines_after_imports=2 known_django=django extra_standard_library=types,requests known_first_party=allauth sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER [flake8] max-line-length = 88 # Black ignore = E203, W503, E501, E231 [mypy] mypy_path = . plugins = mypy_django_plugin.main strict_optional = True disable_error_code = import-untyped, import-not-found [mypy.plugins.django-stubs] django_settings_module = tests.regular.settings django-allauth-65.0.2/setup.py000066400000000000000000000001061467545753200162270ustar00rootroot00000000000000from setuptools import setup if __name__ == "__main__": setup() django-allauth-65.0.2/shell.nix000066400000000000000000000023061467545753200163500ustar00rootroot00000000000000with import {}; stdenv.mkDerivation { name = "django-allauth"; buildInputs = [ black gettext isort djlint python311 python311Packages.mypy python311Packages.django-stubs python311Packages.types-requests python311Packages.django python311Packages.flake8 python311Packages.debugpy python311Packages.pycodestyle python311Packages.pyls-flake8 python311Packages.pylsp-rope python311Packages.pytest python311Packages.pytest-cov python311Packages.pytest-django python311Packages.pytest-asyncio python311Packages.python-lsp-server python311Packages.python3-openid python311Packages.python3-saml python311Packages.pyjwt python311Packages.qrcode python311Packages.sphinx-rtd-theme python311Packages.requests-oauthlib python311Packages.tox python311Packages.daphne python311Packages.fido2 sphinx twine nodejs playwright-test swagger-cli woodpecker-cli ]; shellHook = '' export PATH="$PWD/node_modules/.bin/:$PATH" ''; } django-allauth-65.0.2/tests/000077500000000000000000000000001467545753200156625ustar00rootroot00000000000000django-allauth-65.0.2/tests/__init__.py000066400000000000000000000000001467545753200177610ustar00rootroot00000000000000django-allauth-65.0.2/tests/account_only/000077500000000000000000000000001467545753200203575ustar00rootroot00000000000000django-allauth-65.0.2/tests/account_only/__init__.py000066400000000000000000000000001467545753200224560ustar00rootroot00000000000000django-allauth-65.0.2/tests/account_only/settings.py000066400000000000000000000050351467545753200225740ustar00rootroot00000000000000from pathlib import Path from django.contrib.auth.hashers import PBKDF2PasswordHasher SECRET_KEY = "psst" SITE_ID = 1 ALLOWED_HOSTS = ( "testserver", "example.com", ) USE_I18N = False USE_TZ = True DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", "USER": "", "PASSWORD": "", "HOST": "", "PORT": "", } } ROOT_URLCONF = "tests.account_only.urls" LOGIN_URL = "/accounts/login/" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [Path(__file__).parent / "templates"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] CACHES = { "default": { "BACKEND": "django.core.cache.backends.dummy.DummyCache", } } MIDDLEWARE = ( "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "allauth.account.middleware.AccountMiddleware", ) INSTALLED_APPS = ( "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.admin", "django.contrib.humanize", "allauth", "allauth.account", ) AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) STATIC_ROOT = "/tmp/" # Dummy STATIC_URL = "/static/" class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher): """ A subclass of PBKDF2PasswordHasher that uses 1 iteration. This is for test purposes only. Never use anywhere else. """ iterations = 1 PASSWORD_HASHERS = [ "tests.headless_only.settings.MyPBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", ] ACCOUNT_LOGIN_BY_CODE_ENABLED = True django-allauth-65.0.2/tests/account_only/templates/000077500000000000000000000000001467545753200223555ustar00rootroot00000000000000django-allauth-65.0.2/tests/account_only/templates/429.html000066400000000000000000000000041467545753200235530ustar00rootroot00000000000000429 django-allauth-65.0.2/tests/account_only/urls.py000066400000000000000000000004711467545753200217200ustar00rootroot00000000000000from django.contrib import admin from django.urls import include, path from allauth.account.decorators import secure_admin_login admin.autodiscover() admin.site.login = secure_admin_login(admin.site.login) urlpatterns = [ path("admin/", admin.site.urls), path("accounts/", include("allauth.urls")), ] django-allauth-65.0.2/tests/headless_only/000077500000000000000000000000001467545753200205135ustar00rootroot00000000000000django-allauth-65.0.2/tests/headless_only/__init__.py000066400000000000000000000000001467545753200226120ustar00rootroot00000000000000django-allauth-65.0.2/tests/headless_only/settings.py000066400000000000000000000226551467545753200227370ustar00rootroot00000000000000from pathlib import Path from django.contrib.auth.hashers import PBKDF2PasswordHasher SECRET_KEY = "psst" SITE_ID = 1 ALLOWED_HOSTS = ( "testserver", "example.com", ) USE_I18N = False USE_TZ = True DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", "USER": "", "PASSWORD": "", "HOST": "", "PORT": "", } } ROOT_URLCONF = "tests.headless_only.urls" LOGIN_URL = "/login/" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [ Path(__file__).parent.parent / "examples" / "regular-django" / "example" / "templates" ], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] CACHES = { "default": { "BACKEND": "django.core.cache.backends.dummy.DummyCache", } } MIDDLEWARE = ( "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "allauth.account.middleware.AccountMiddleware", ) INSTALLED_APPS = ( "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.admin", "django.contrib.humanize", "allauth", "allauth.account", "allauth.mfa", "allauth.socialaccount", "allauth.socialaccount.providers.agave", "allauth.socialaccount.providers.amazon", "allauth.socialaccount.providers.amazon_cognito", "allauth.socialaccount.providers.angellist", "allauth.socialaccount.providers.apple", "allauth.socialaccount.providers.asana", "allauth.socialaccount.providers.atlassian", "allauth.socialaccount.providers.auth0", "allauth.socialaccount.providers.authentiq", "allauth.socialaccount.providers.baidu", "allauth.socialaccount.providers.basecamp", "allauth.socialaccount.providers.battlenet", "allauth.socialaccount.providers.bitbucket_oauth2", "allauth.socialaccount.providers.bitly", "allauth.socialaccount.providers.box", "allauth.socialaccount.providers.cilogon", "allauth.socialaccount.providers.clever", "allauth.socialaccount.providers.coinbase", "allauth.socialaccount.providers.dataporten", "allauth.socialaccount.providers.daum", "allauth.socialaccount.providers.digitalocean", "allauth.socialaccount.providers.dingtalk", "allauth.socialaccount.providers.discord", "allauth.socialaccount.providers.disqus", "allauth.socialaccount.providers.douban", "allauth.socialaccount.providers.doximity", "allauth.socialaccount.providers.draugiem", "allauth.socialaccount.providers.drip", "allauth.socialaccount.providers.dropbox", "allauth.socialaccount.providers.dummy", "allauth.socialaccount.providers.dwolla", "allauth.socialaccount.providers.edmodo", "allauth.socialaccount.providers.edx", "allauth.socialaccount.providers.eventbrite", "allauth.socialaccount.providers.eveonline", "allauth.socialaccount.providers.evernote", "allauth.socialaccount.providers.exist", "allauth.socialaccount.providers.facebook", "allauth.socialaccount.providers.feedly", "allauth.socialaccount.providers.figma", "allauth.socialaccount.providers.fivehundredpx", "allauth.socialaccount.providers.flickr", "allauth.socialaccount.providers.foursquare", "allauth.socialaccount.providers.frontier", "allauth.socialaccount.providers.fxa", "allauth.socialaccount.providers.gitea", "allauth.socialaccount.providers.github", "allauth.socialaccount.providers.gitlab", "allauth.socialaccount.providers.globus", "allauth.socialaccount.providers.google", "allauth.socialaccount.providers.gumroad", "allauth.socialaccount.providers.hubic", "allauth.socialaccount.providers.hubspot", "allauth.socialaccount.providers.instagram", "allauth.socialaccount.providers.jupyterhub", "allauth.socialaccount.providers.kakao", "allauth.socialaccount.providers.lemonldap", "allauth.socialaccount.providers.line", "allauth.socialaccount.providers.linkedin_oauth2", "allauth.socialaccount.providers.mailchimp", "allauth.socialaccount.providers.mailru", "allauth.socialaccount.providers.mediawiki", "allauth.socialaccount.providers.meetup", "allauth.socialaccount.providers.microsoft", "allauth.socialaccount.providers.miro", "allauth.socialaccount.providers.naver", "allauth.socialaccount.providers.netiq", "allauth.socialaccount.providers.nextcloud", "allauth.socialaccount.providers.notion", "allauth.socialaccount.providers.odnoklassniki", "allauth.socialaccount.providers.openid", "allauth.socialaccount.providers.openid_connect", "allauth.socialaccount.providers.openstreetmap", "allauth.socialaccount.providers.orcid", "allauth.socialaccount.providers.patreon", "allauth.socialaccount.providers.paypal", "allauth.socialaccount.providers.pinterest", "allauth.socialaccount.providers.pocket", "allauth.socialaccount.providers.questrade", "allauth.socialaccount.providers.quickbooks", "allauth.socialaccount.providers.reddit", "allauth.socialaccount.providers.robinhood", "allauth.socialaccount.providers.salesforce", "allauth.socialaccount.providers.saml", "allauth.socialaccount.providers.sharefile", "allauth.socialaccount.providers.shopify", "allauth.socialaccount.providers.slack", "allauth.socialaccount.providers.snapchat", "allauth.socialaccount.providers.soundcloud", "allauth.socialaccount.providers.spotify", "allauth.socialaccount.providers.stackexchange", "allauth.socialaccount.providers.steam", "allauth.socialaccount.providers.stocktwits", "allauth.socialaccount.providers.strava", "allauth.socialaccount.providers.stripe", "allauth.socialaccount.providers.telegram", "allauth.socialaccount.providers.trainingpeaks", "allauth.socialaccount.providers.trello", "allauth.socialaccount.providers.tumblr", "allauth.socialaccount.providers.twentythreeandme", "allauth.socialaccount.providers.twitch", "allauth.socialaccount.providers.twitter", "allauth.socialaccount.providers.twitter_oauth2", "allauth.socialaccount.providers.untappd", "allauth.socialaccount.providers.vimeo", "allauth.socialaccount.providers.vimeo_oauth2", "allauth.socialaccount.providers.vk", "allauth.socialaccount.providers.wahoo", "allauth.socialaccount.providers.weibo", "allauth.socialaccount.providers.weixin", "allauth.socialaccount.providers.windowslive", "allauth.socialaccount.providers.xing", "allauth.socialaccount.providers.yahoo", "allauth.socialaccount.providers.yandex", "allauth.socialaccount.providers.ynab", "allauth.socialaccount.providers.zoho", "allauth.socialaccount.providers.zoom", "allauth.socialaccount.providers.okta", "allauth.socialaccount.providers.feishu", "allauth.usersessions", "allauth.headless", ) AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) STATIC_ROOT = "/tmp/" # Dummy STATIC_URL = "/static/" class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher): """ A subclass of PBKDF2PasswordHasher that uses 1 iteration. This is for test purposes only. Never use anywhere else. """ iterations = 1 PASSWORD_HASHERS = [ "tests.headless_only.settings.MyPBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", ] SOCIALACCOUNT_QUERY_EMAIL = True SOCIALACCOUNT_PROVIDERS = { "openid_connect": { "APPS": [ { "provider_id": "unittest-server", "name": "Unittest Server", "client_id": "Unittest client_id", "client_secret": "Unittest client_secret", "settings": { "server_url": "https://unittest.example.com", }, }, { "provider_id": "other-server", "name": "Other Example Server", "client_id": "other client_id", "client_secret": "other client_secret", "settings": { "server_url": "https://other.example.com", }, }, ], } } ACCOUNT_LOGIN_BY_CODE_ENABLED = True HEADLESS_ONLY = True HEADLESS_FRONTEND_URLS = { "account_confirm_email": "/spa/confirm-email?key={key}", "account_reset_password": "/spa/password/reset/", "account_reset_password_from_key": "/spa/password/reset/{key}/", "account_signup": "/spa/signup", } MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes"] MFA_PASSKEY_LOGIN_ENABLED = True MFA_PASSKEY_SIGNUP_ENABLED = True django-allauth-65.0.2/tests/headless_only/urls.py000066400000000000000000000002431467545753200220510ustar00rootroot00000000000000from django.urls import include, path urlpatterns = [ path("accounts/", include("allauth.urls")), path("_allauth/", include("allauth.headless.urls")), ] django-allauth-65.0.2/tests/login_required_mw/000077500000000000000000000000001467545753200213755ustar00rootroot00000000000000django-allauth-65.0.2/tests/login_required_mw/__init__.py000066400000000000000000000000001467545753200234740ustar00rootroot00000000000000django-allauth-65.0.2/tests/login_required_mw/settings.py000066400000000000000000000223201467545753200236060ustar00rootroot00000000000000from pathlib import Path from django.contrib.auth.hashers import PBKDF2PasswordHasher SECRET_KEY = "psst" SITE_ID = 1 ALLOWED_HOSTS = ( "testserver", "example.com", ) USE_I18N = False USE_TZ = True DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", "USER": "", "PASSWORD": "", "HOST": "", "PORT": "", } } ROOT_URLCONF = "tests.login_required_mw.urls" LOGIN_URL = "/accounts/login/" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [Path(__file__).parent / "templates"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] CACHES = { "default": { "BACKEND": "django.core.cache.backends.dummy.DummyCache", } } MIDDLEWARE = ( "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.auth.middleware.LoginRequiredMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "allauth.account.middleware.AccountMiddleware", ) INSTALLED_APPS = ( "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.admin", "django.contrib.humanize", "allauth", "allauth.account", "allauth.mfa", "allauth.socialaccount", "allauth.socialaccount.providers.agave", "allauth.socialaccount.providers.amazon", "allauth.socialaccount.providers.amazon_cognito", "allauth.socialaccount.providers.angellist", "allauth.socialaccount.providers.apple", "allauth.socialaccount.providers.asana", "allauth.socialaccount.providers.atlassian", "allauth.socialaccount.providers.auth0", "allauth.socialaccount.providers.authentiq", "allauth.socialaccount.providers.baidu", "allauth.socialaccount.providers.basecamp", "allauth.socialaccount.providers.battlenet", "allauth.socialaccount.providers.bitbucket_oauth2", "allauth.socialaccount.providers.bitly", "allauth.socialaccount.providers.box", "allauth.socialaccount.providers.cilogon", "allauth.socialaccount.providers.clever", "allauth.socialaccount.providers.coinbase", "allauth.socialaccount.providers.dataporten", "allauth.socialaccount.providers.daum", "allauth.socialaccount.providers.digitalocean", "allauth.socialaccount.providers.dingtalk", "allauth.socialaccount.providers.discord", "allauth.socialaccount.providers.disqus", "allauth.socialaccount.providers.douban", "allauth.socialaccount.providers.doximity", "allauth.socialaccount.providers.draugiem", "allauth.socialaccount.providers.drip", "allauth.socialaccount.providers.dropbox", "allauth.socialaccount.providers.dummy", "allauth.socialaccount.providers.dwolla", "allauth.socialaccount.providers.edmodo", "allauth.socialaccount.providers.edx", "allauth.socialaccount.providers.eventbrite", "allauth.socialaccount.providers.eveonline", "allauth.socialaccount.providers.evernote", "allauth.socialaccount.providers.exist", "allauth.socialaccount.providers.facebook", "allauth.socialaccount.providers.feedly", "allauth.socialaccount.providers.figma", "allauth.socialaccount.providers.fivehundredpx", "allauth.socialaccount.providers.flickr", "allauth.socialaccount.providers.foursquare", "allauth.socialaccount.providers.frontier", "allauth.socialaccount.providers.fxa", "allauth.socialaccount.providers.gitea", "allauth.socialaccount.providers.github", "allauth.socialaccount.providers.gitlab", "allauth.socialaccount.providers.globus", "allauth.socialaccount.providers.google", "allauth.socialaccount.providers.gumroad", "allauth.socialaccount.providers.hubic", "allauth.socialaccount.providers.hubspot", "allauth.socialaccount.providers.instagram", "allauth.socialaccount.providers.jupyterhub", "allauth.socialaccount.providers.kakao", "allauth.socialaccount.providers.lemonldap", "allauth.socialaccount.providers.lichess", "allauth.socialaccount.providers.line", "allauth.socialaccount.providers.linkedin_oauth2", "allauth.socialaccount.providers.mailchimp", "allauth.socialaccount.providers.mailru", "allauth.socialaccount.providers.mediawiki", "allauth.socialaccount.providers.meetup", "allauth.socialaccount.providers.microsoft", "allauth.socialaccount.providers.miro", "allauth.socialaccount.providers.naver", "allauth.socialaccount.providers.netiq", "allauth.socialaccount.providers.nextcloud", "allauth.socialaccount.providers.notion", "allauth.socialaccount.providers.odnoklassniki", "allauth.socialaccount.providers.openid", "allauth.socialaccount.providers.openid_connect", "allauth.socialaccount.providers.openstreetmap", "allauth.socialaccount.providers.orcid", "allauth.socialaccount.providers.patreon", "allauth.socialaccount.providers.paypal", "allauth.socialaccount.providers.pinterest", "allauth.socialaccount.providers.pocket", "allauth.socialaccount.providers.questrade", "allauth.socialaccount.providers.quickbooks", "allauth.socialaccount.providers.reddit", "allauth.socialaccount.providers.robinhood", "allauth.socialaccount.providers.salesforce", "allauth.socialaccount.providers.saml", "allauth.socialaccount.providers.sharefile", "allauth.socialaccount.providers.shopify", "allauth.socialaccount.providers.slack", "allauth.socialaccount.providers.snapchat", "allauth.socialaccount.providers.soundcloud", "allauth.socialaccount.providers.spotify", "allauth.socialaccount.providers.stackexchange", "allauth.socialaccount.providers.steam", "allauth.socialaccount.providers.stocktwits", "allauth.socialaccount.providers.strava", "allauth.socialaccount.providers.stripe", "allauth.socialaccount.providers.telegram", "allauth.socialaccount.providers.tiktok", "allauth.socialaccount.providers.trainingpeaks", "allauth.socialaccount.providers.trello", "allauth.socialaccount.providers.tumblr", "allauth.socialaccount.providers.twentythreeandme", "allauth.socialaccount.providers.twitch", "allauth.socialaccount.providers.twitter", "allauth.socialaccount.providers.twitter_oauth2", "allauth.socialaccount.providers.untappd", "allauth.socialaccount.providers.vimeo", "allauth.socialaccount.providers.vimeo_oauth2", "allauth.socialaccount.providers.vk", "allauth.socialaccount.providers.wahoo", "allauth.socialaccount.providers.weibo", "allauth.socialaccount.providers.weixin", "allauth.socialaccount.providers.windowslive", "allauth.socialaccount.providers.xing", "allauth.socialaccount.providers.yahoo", "allauth.socialaccount.providers.yandex", "allauth.socialaccount.providers.ynab", "allauth.socialaccount.providers.zoho", "allauth.socialaccount.providers.zoom", "allauth.socialaccount.providers.okta", "allauth.socialaccount.providers.feishu", "allauth.usersessions", "allauth.headless", ) AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) STATIC_ROOT = "/tmp/" # Dummy STATIC_URL = "/static/" class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher): """ A subclass of PBKDF2PasswordHasher that uses 1 iteration. This is for test purposes only. Never use anywhere else. """ iterations = 1 PASSWORD_HASHERS = [ "tests.login_required_mw.settings.MyPBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", ] SOCIALACCOUNT_QUERY_EMAIL = True SOCIALACCOUNT_PROVIDERS = { "openid_connect": { "APPS": [ { "provider_id": "unittest-server", "name": "Unittest Server", "client_id": "Unittest client_id", "client_secret": "Unittest client_secret", "settings": { "server_url": "https://unittest.example.com", }, }, { "provider_id": "other-server", "name": "Other Example Server", "client_id": "other client_id", "client_secret": "other client_secret", "settings": { "server_url": "https://other.example.com", }, }, ], } } ACCOUNT_LOGIN_BY_CODE_ENABLED = True MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes"] MFA_PASSKEY_LOGIN_ENABLED = True MFA_PASSKEY_SIGNUP_ENABLED = True django-allauth-65.0.2/tests/login_required_mw/templates/000077500000000000000000000000001467545753200233735ustar00rootroot00000000000000django-allauth-65.0.2/tests/login_required_mw/templates/429.html000066400000000000000000000000041467545753200245710ustar00rootroot00000000000000429 django-allauth-65.0.2/tests/login_required_mw/urls.py000066400000000000000000000005631467545753200227400ustar00rootroot00000000000000from django.contrib import admin from django.urls import include, path from allauth.account.decorators import secure_admin_login admin.autodiscover() admin.site.login = secure_admin_login(admin.site.login) urlpatterns = [ path("admin/", admin.site.urls), path("accounts/", include("allauth.urls")), path("_allauth/", include("allauth.headless.urls")), ] django-allauth-65.0.2/tests/regular/000077500000000000000000000000001467545753200173235ustar00rootroot00000000000000django-allauth-65.0.2/tests/regular/__init__.py000066400000000000000000000000001467545753200214220ustar00rootroot00000000000000django-allauth-65.0.2/tests/regular/settings.py000066400000000000000000000221761467545753200215450ustar00rootroot00000000000000from pathlib import Path from django.contrib.auth.hashers import PBKDF2PasswordHasher SECRET_KEY = "psst" SITE_ID = 1 ALLOWED_HOSTS = ( "testserver", "example.com", ) USE_I18N = False USE_TZ = True DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", "USER": "", "PASSWORD": "", "HOST": "", "PORT": "", } } ROOT_URLCONF = "tests.regular.urls" LOGIN_URL = "/accounts/login/" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [Path(__file__).parent / "templates"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] CACHES = { "default": { "BACKEND": "django.core.cache.backends.dummy.DummyCache", } } MIDDLEWARE = ( "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "allauth.account.middleware.AccountMiddleware", ) INSTALLED_APPS = ( "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.admin", "django.contrib.humanize", "allauth", "allauth.account", "allauth.mfa", "allauth.socialaccount", "allauth.socialaccount.providers.agave", "allauth.socialaccount.providers.amazon", "allauth.socialaccount.providers.amazon_cognito", "allauth.socialaccount.providers.angellist", "allauth.socialaccount.providers.apple", "allauth.socialaccount.providers.asana", "allauth.socialaccount.providers.atlassian", "allauth.socialaccount.providers.auth0", "allauth.socialaccount.providers.authentiq", "allauth.socialaccount.providers.baidu", "allauth.socialaccount.providers.basecamp", "allauth.socialaccount.providers.battlenet", "allauth.socialaccount.providers.bitbucket_oauth2", "allauth.socialaccount.providers.bitly", "allauth.socialaccount.providers.box", "allauth.socialaccount.providers.cilogon", "allauth.socialaccount.providers.clever", "allauth.socialaccount.providers.coinbase", "allauth.socialaccount.providers.dataporten", "allauth.socialaccount.providers.daum", "allauth.socialaccount.providers.digitalocean", "allauth.socialaccount.providers.dingtalk", "allauth.socialaccount.providers.discord", "allauth.socialaccount.providers.disqus", "allauth.socialaccount.providers.douban", "allauth.socialaccount.providers.doximity", "allauth.socialaccount.providers.draugiem", "allauth.socialaccount.providers.drip", "allauth.socialaccount.providers.dropbox", "allauth.socialaccount.providers.dummy", "allauth.socialaccount.providers.dwolla", "allauth.socialaccount.providers.edmodo", "allauth.socialaccount.providers.edx", "allauth.socialaccount.providers.eventbrite", "allauth.socialaccount.providers.eveonline", "allauth.socialaccount.providers.evernote", "allauth.socialaccount.providers.exist", "allauth.socialaccount.providers.facebook", "allauth.socialaccount.providers.feedly", "allauth.socialaccount.providers.figma", "allauth.socialaccount.providers.fivehundredpx", "allauth.socialaccount.providers.flickr", "allauth.socialaccount.providers.foursquare", "allauth.socialaccount.providers.frontier", "allauth.socialaccount.providers.fxa", "allauth.socialaccount.providers.gitea", "allauth.socialaccount.providers.github", "allauth.socialaccount.providers.gitlab", "allauth.socialaccount.providers.globus", "allauth.socialaccount.providers.google", "allauth.socialaccount.providers.gumroad", "allauth.socialaccount.providers.hubic", "allauth.socialaccount.providers.hubspot", "allauth.socialaccount.providers.instagram", "allauth.socialaccount.providers.jupyterhub", "allauth.socialaccount.providers.kakao", "allauth.socialaccount.providers.lemonldap", "allauth.socialaccount.providers.lichess", "allauth.socialaccount.providers.line", "allauth.socialaccount.providers.linkedin_oauth2", "allauth.socialaccount.providers.mailchimp", "allauth.socialaccount.providers.mailru", "allauth.socialaccount.providers.mediawiki", "allauth.socialaccount.providers.meetup", "allauth.socialaccount.providers.microsoft", "allauth.socialaccount.providers.miro", "allauth.socialaccount.providers.naver", "allauth.socialaccount.providers.netiq", "allauth.socialaccount.providers.nextcloud", "allauth.socialaccount.providers.notion", "allauth.socialaccount.providers.odnoklassniki", "allauth.socialaccount.providers.openid", "allauth.socialaccount.providers.openid_connect", "allauth.socialaccount.providers.openstreetmap", "allauth.socialaccount.providers.orcid", "allauth.socialaccount.providers.patreon", "allauth.socialaccount.providers.paypal", "allauth.socialaccount.providers.pinterest", "allauth.socialaccount.providers.pocket", "allauth.socialaccount.providers.questrade", "allauth.socialaccount.providers.quickbooks", "allauth.socialaccount.providers.reddit", "allauth.socialaccount.providers.robinhood", "allauth.socialaccount.providers.salesforce", "allauth.socialaccount.providers.saml", "allauth.socialaccount.providers.sharefile", "allauth.socialaccount.providers.shopify", "allauth.socialaccount.providers.slack", "allauth.socialaccount.providers.snapchat", "allauth.socialaccount.providers.soundcloud", "allauth.socialaccount.providers.spotify", "allauth.socialaccount.providers.stackexchange", "allauth.socialaccount.providers.steam", "allauth.socialaccount.providers.stocktwits", "allauth.socialaccount.providers.strava", "allauth.socialaccount.providers.stripe", "allauth.socialaccount.providers.telegram", "allauth.socialaccount.providers.tiktok", "allauth.socialaccount.providers.trainingpeaks", "allauth.socialaccount.providers.trello", "allauth.socialaccount.providers.tumblr", "allauth.socialaccount.providers.twentythreeandme", "allauth.socialaccount.providers.twitch", "allauth.socialaccount.providers.twitter", "allauth.socialaccount.providers.twitter_oauth2", "allauth.socialaccount.providers.untappd", "allauth.socialaccount.providers.vimeo", "allauth.socialaccount.providers.vimeo_oauth2", "allauth.socialaccount.providers.vk", "allauth.socialaccount.providers.wahoo", "allauth.socialaccount.providers.weibo", "allauth.socialaccount.providers.weixin", "allauth.socialaccount.providers.windowslive", "allauth.socialaccount.providers.xing", "allauth.socialaccount.providers.yahoo", "allauth.socialaccount.providers.yandex", "allauth.socialaccount.providers.ynab", "allauth.socialaccount.providers.zoho", "allauth.socialaccount.providers.zoom", "allauth.socialaccount.providers.okta", "allauth.socialaccount.providers.feishu", "allauth.usersessions", "allauth.headless", ) AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) STATIC_ROOT = "/tmp/" # Dummy STATIC_URL = "/static/" class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher): """ A subclass of PBKDF2PasswordHasher that uses 1 iteration. This is for test purposes only. Never use anywhere else. """ iterations = 1 PASSWORD_HASHERS = [ "tests.regular.settings.MyPBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", ] SOCIALACCOUNT_QUERY_EMAIL = True SOCIALACCOUNT_PROVIDERS = { "openid_connect": { "APPS": [ { "provider_id": "unittest-server", "name": "Unittest Server", "client_id": "Unittest client_id", "client_secret": "Unittest client_secret", "settings": { "server_url": "https://unittest.example.com", }, }, { "provider_id": "other-server", "name": "Other Example Server", "client_id": "other client_id", "client_secret": "other client_secret", "settings": { "server_url": "https://other.example.com", }, }, ], } } ACCOUNT_LOGIN_BY_CODE_ENABLED = True MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes"] MFA_PASSKEY_LOGIN_ENABLED = True MFA_PASSKEY_SIGNUP_ENABLED = True django-allauth-65.0.2/tests/regular/templates/000077500000000000000000000000001467545753200213215ustar00rootroot00000000000000django-allauth-65.0.2/tests/regular/templates/429.html000066400000000000000000000000041467545753200225170ustar00rootroot00000000000000429 django-allauth-65.0.2/tests/regular/urls.py000066400000000000000000000005631467545753200206660ustar00rootroot00000000000000from django.contrib import admin from django.urls import include, path from allauth.account.decorators import secure_admin_login admin.autodiscover() admin.site.login = secure_admin_login(admin.site.login) urlpatterns = [ path("admin/", admin.site.urls), path("accounts/", include("allauth.urls")), path("_allauth/", include("allauth.headless.urls")), ] django-allauth-65.0.2/tox.ini000066400000000000000000000056271467545753200160450ustar00rootroot00000000000000[tox] envlist = prj{regular,headless_only}-py{38,39,310,311,312}-django{42} prj{regular,headless_only}-py{310,311,312}-django{50,51} prj{regular,headless_only}-py{310,311,312}-djangomain prj{login_required_mw}-py{312}-django{51} docs isort black flake8 mypy standardjs compilemessages [testenv] setenv = PYTHONWARNINGS = all prjregular: DJANGO_SETTINGS_MODULE = tests.regular.settings prjlogin_required_mw: DJANGO_SETTINGS_MODULE = tests.login_required_mw.settings prjheadless_only: DJANGO_SETTINGS_MODULE = tests.headless_only.settings deps = coverage==7.6.1 Pillow>=9.0 pytest>=7.4 pytest-asyncio == 0.23.8 pytest-django>=4.5.2 django42: Django==4.2.* django50: Django==5.0.* django51: Django==5.1.* djangomain: git+https://github.com/django/django.git@main#egg=django python3-saml>=1.15.0,<2.0.0 extras = mfa openid socialaccount steam commands = coverage run -m pytest --ds={env:DJANGO_SETTINGS_MODULE} {posargs:allauth} coverage report coverage html allowlist_externals = /usr/bin/env make [testenv:docs] skip_install = True deps = Django Sphinx sphinx_rtd_theme whitelist_externals = make commands = make -C {toxinidir}/docs html [testenv:isort] skip_install = True deps = isort==5.13.2 commands = isort --check-only --diff {posargs:{toxinidir}} [testenv:black] skip_install = True deps = black==24.4.0 commands = black --check {posargs:{toxinidir}} [testenv:djlint] skip_install = True deps = djlint==1.34.1 commands = djlint --configuration {posargs:{toxinidir}/.djlintrc} --check {posargs:{toxinidir}/allauth} {posargs:{toxinidir}/examples} [testenv:flake8] skip_install = True deps = flake8==6.0.0 commands = flake8 {posargs:{toxinidir}/allauth} [testenv:mypy] deps = django-stubs==5.0.2 mypy==1.10.0 pytest>=7.4 pytest-asyncio == 0.23.8 pytest-django>=4.5.2 types-requests==2.32.0.20240602 python3-saml>=1.15.0,<2.0.0 commands = mypy {posargs:{toxinidir}/allauth} [testenv:compilemessages] skip_install = True deps = Django commands = /usr/bin/env bash -c "cd allauth; python ../manage.py compilemessages" setenv = DJANGO_SETTINGS_MODULE = tests.account_only.settings [testenv:standardjs] skip_install = True commands = /usr/bin/env bash -c "mkdir -p {toxinidir}/node_modules" /usr/bin/env npm install standard --no-lockfile --no-progress --non-interactive --silent /usr/bin/env bash -c "find {toxinidir}/allauth -name '*.js' | xargs {toxinidir}/node_modules/.bin/standard" [coverage:run] include = allauth* [gh-actions:env] PYTHON_VER = 3.8: py38 3.9: py39 3.10: py310 3.11: py311 3.12: py312 DJANGO = main: djangomain 4.2: django42 5.0: django50 5.1: django51 PRJ = regular: prjregular headless_only: prjheadless_only login_required_mw: prjlogin_required_mw