Loading poetry.lock +20 −56 Original line number Diff line number Diff line # This file is automatically @generated by Poetry and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "asgiref" version = "3.8.1" description = "ASGI specs, helper code, and adapters" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -19,7 +18,6 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "async-stripe" version = "5.5.0" description = "An asynchronous wrapper around Stripe's official python library." category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ Loading @@ -35,7 +33,6 @@ tornado = ">=5.1" name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -47,7 +44,6 @@ files = [ name = "beautifulsoup4" version = "4.12.3" description = "Screen-scraping library" category = "main" optional = false python-versions = ">=3.6.0" files = [ Loading @@ -69,7 +65,6 @@ lxml = ["lxml"] name = "certifi" version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" files = [ Loading @@ -81,7 +76,6 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false python-versions = ">=3.7.0" files = [ Loading Loading @@ -181,7 +175,6 @@ files = [ name = "coverage" version = "7.6.1" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading Loading @@ -266,7 +259,6 @@ toml = ["tomli"] name = "dependency-injector" version = "4.41.0" description = "Dependency injection framework for Python" category = "main" optional = false python-versions = "*" files = [ Loading Loading @@ -355,7 +347,6 @@ yaml = ["pyyaml"] name = "django" version = "4.2.15" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -376,7 +367,6 @@ bcrypt = ["bcrypt"] name = "django-bootstrap-v5" version = "1.0.11" description = "Bootstrap 5 support for Django projects" category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ Loading @@ -395,7 +385,6 @@ docs = ["m2r2 (>=0.2.5,<0.3.0)", "sphinx (>=4.4,<5.0)", "sphinx_rtd_theme (>=1.0 name = "django-jinja" version = "2.11.0" description = "Jinja2 templating language integrated in Django." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -411,7 +400,6 @@ jinja2 = ">=3" name = "django-jinja-bootstrap-form" version = "4.5.0" description = "django-jinja-bootstrap-form" category = "main" optional = false python-versions = ">=3.6" files = [ Loading @@ -427,7 +415,6 @@ django-jinja = ">=2.6.0" name = "django-prometheus" version = "2.3.1" description = "Django middlewares to monitor your application with Prometheus.io." category = "main" optional = false python-versions = "*" files = [ Loading @@ -442,7 +429,6 @@ prometheus-client = ">=0.7" name = "django-ranged-response" version = "0.2.0" description = "Modified Django FileResponse that adds Content-Range headers." category = "main" optional = false python-versions = "*" files = [ Loading @@ -456,7 +442,6 @@ django = "*" name = "django-ratelimit" version = "4.1.0" description = "Cache-based rate-limiting for Django." category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -468,7 +453,6 @@ files = [ name = "django-simple-captcha" version = "0.6.1" description = "A very simple, yet powerful, Django captcha application" category = "main" optional = false python-versions = "*" files = [] Loading @@ -477,6 +461,7 @@ develop = false [package.dependencies] Django = ">=4.2" django-ranged-response = "0.2.0" djangorestframework = ">=3.15.0" Pillow = ">=6.2.0" [package.extras] Loading @@ -485,14 +470,27 @@ test = ["testfixtures"] [package.source] type = "git" url = "https://github.com/mbi/django-simple-captcha.git" reference = "bf7fffc01b989ab411bbc29d7b27c465a0ba5289" resolved_reference = "bf7fffc01b989ab411bbc29d7b27c465a0ba5289" reference = "1c92409dd05475a94657711a048732228bf6288a" resolved_reference = "1c92409dd05475a94657711a048732228bf6288a" [[package]] name = "djangorestframework" version = "3.15.2" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.8" files = [ {file = "djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20"}, {file = "djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad"}, ] [package.dependencies] django = ">=4.2" [[package]] name = "dnspython" version = "2.6.1" description = "DNS toolkit" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -513,7 +511,6 @@ wmi = ["wmi (>=1.5.1)"] name = "email-validator" version = "2.2.0" description = "A robust email address syntax and deliverability validation library." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -529,7 +526,6 @@ idna = ">=2.0.0" name = "fakeredis" version = "2.24.1" description = "Python implementation of redis API, can be used for testing purposes." category = "dev" optional = false python-versions = "<4.0,>=3.7" files = [ Loading @@ -552,7 +548,6 @@ probabilistic = ["pyprobables (>=0.6,<0.7)"] name = "flake8" version = "6.1.0" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false python-versions = ">=3.8.1" files = [ Loading @@ -569,7 +564,6 @@ pyflakes = ">=3.1.0,<3.2.0" name = "flake8-isort" version = "6.1.1" description = "flake8 plugin that integrates isort" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -588,7 +582,6 @@ test = ["pytest"] name = "flake8-pyproject" version = "1.2.3" description = "Flake8 plug-in loading the configuration from pyproject.toml" category = "dev" optional = false python-versions = ">= 3.6" files = [ Loading @@ -605,7 +598,6 @@ dev = ["pyTest", "pyTest-cov"] name = "gunicorn" version = "20.1.0" description = "WSGI HTTP Server for UNIX" category = "dev" optional = false python-versions = ">=3.5" files = [ Loading @@ -626,7 +618,6 @@ tornado = ["tornado (>=0.2)"] name = "idna" version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false python-versions = ">=3.6" files = [ Loading @@ -638,7 +629,6 @@ files = [ name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." category = "dev" optional = false python-versions = ">=3.8.0" files = [ Loading @@ -653,7 +643,6 @@ colors = ["colorama (>=0.4.6)"] name = "jinja2" version = "3.1.4" description = "A very fast and expressive template engine." category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -671,7 +660,6 @@ i18n = ["Babel (>=2.7)"] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false python-versions = ">=3.7" files = [ Loading Loading @@ -741,7 +729,6 @@ files = [ name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = ">=3.6" files = [ Loading @@ -753,7 +740,6 @@ files = [ name = "mypy" version = "1.11.2" description = "Optional static typing for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading Loading @@ -800,7 +786,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false python-versions = ">=3.5" files = [ Loading @@ -812,7 +797,6 @@ files = [ name = "pillow" version = "10.4.0" description = "Python Imaging Library (Fork)" category = "main" optional = false python-versions = ">=3.8" files = [ Loading Loading @@ -910,7 +894,6 @@ xmp = ["defusedxml"] name = "prometheus-client" version = "0.20.0" description = "Python client for the Prometheus monitoring system." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -925,7 +908,6 @@ twisted = ["twisted"] name = "pycodestyle" version = "2.11.1" description = "Python style guide checker" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -937,7 +919,6 @@ files = [ name = "pyflakes" version = "3.1.0" description = "passive checker of Python programs" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -949,7 +930,6 @@ files = [ name = "python-dotenv" version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -964,7 +944,6 @@ cli = ["click (>=5.0)"] name = "redis" version = "5.0.8" description = "Python client for Redis database and key-value store" category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -983,7 +962,6 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "requests" version = "2.32.3" description = "Python HTTP for Humans." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1005,7 +983,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-mock" version = "1.12.1" description = "Mock out responses from the requests package" category = "dev" optional = false python-versions = ">=3.5" files = [ Loading @@ -1023,7 +1000,6 @@ fixture = ["fixtures"] name = "setuptools" version = "74.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -1038,13 +1014,12 @@ cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.11.0,<1.12.0)", "pytest-mypy"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ Loading @@ -1056,7 +1031,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" category = "dev" optional = false python-versions = "*" files = [ Loading @@ -1068,7 +1042,6 @@ files = [ name = "soupsieve" version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1080,7 +1053,6 @@ files = [ name = "sqlparse" version = "0.5.1" description = "A non-validating SQL parser." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1096,7 +1068,6 @@ doc = ["sphinx"] name = "stripe" version = "5.5.0" description = "Python bindings for the Stripe API" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ Loading @@ -1111,7 +1082,6 @@ requests = {version = ">=2.20", markers = "python_version >= \"3.0\""} name = "tomli" version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false python-versions = ">=3.7" files = [ Loading @@ -1123,7 +1093,6 @@ files = [ name = "tornado" version = "6.4.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1144,7 +1113,6 @@ files = [ name = "types-requests" version = "2.32.0.20240712" description = "Typing stubs for requests" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1159,7 +1127,6 @@ urllib3 = ">=2" name = "types-stripe" version = "3.5.2.20240106" description = "Typing stubs for stripe" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1171,7 +1138,6 @@ files = [ name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -1183,7 +1149,6 @@ files = [ name = "tzdata" version = "2024.1" description = "Provider of IANA time zone data" category = "main" optional = false python-versions = ">=2" files = [ Loading @@ -1195,7 +1160,6 @@ files = [ name = "urllib3" version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1212,4 +1176,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.11" content-hash = "aa40551da0d21287e2177518c6f023f2e62ee6ddf2c75df8c25addf5760d51de" content-hash = "da05afb7869c76f57a76c97e157e76b748605e6854067eee7bbf5888932f56fb" pyproject.toml +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.11" Django = "^4.2.4" django-simple-captcha = { git = "https://github.com/mbi/django-simple-captcha.git", rev = "bf7fffc01b989ab411bbc29d7b27c465a0ba5289" } django-simple-captcha = { git = "https://github.com/mbi/django-simple-captcha.git", rev = "1c92409dd05475a94657711a048732228bf6288a" } django-bootstrap-v5 = "^1.0.11" django-jinja = "^2.10.2" django-jinja-bootstrap-form = "^4.5.0" Loading static/js/script.js +3 −3 Original line number Diff line number Diff line Loading @@ -61,12 +61,12 @@ dTor.init = function () { $("form.was-validated").removeClass("was-validated"); dTor.refreshCaptcha(); const messageContainer = $("#result-message"); messageContainer.html(message).removeClass("hidden"); messageContainer.text(message).removeClass("hidden"); }; this.hidePaymentError = function() { const messageContainer = $("#result-message"); messageContainer.html("").addClass("hidden"); messageContainer.text("").addClass("hidden"); } this.handleFormErrors = function (errors) { Loading Loading @@ -118,7 +118,7 @@ dTor.init = function () { this.validateElement = function (el) { if (!el.checkValidity() || $(el).val() == null) { $(el).siblings(".invalid-feedback").html(el.validationMessage); $(el).siblings(".invalid-feedback").text(el.validationMessage); $(el).addClass("is-invalid"); } else { $(el).removeClass("is-invalid"); Loading tordonate/paypal/controller.py +18 −7 Original line number Diff line number Diff line Loading @@ -331,8 +331,10 @@ If this error persists, please reach out to us via one of the methods # IPN timestamp info: https://developer.paypal.com/api/nvp-soap/ipn/IPNandPDTVariables/#payment-information # noqa: E501 # Relevant Python Github issue regarding strptime's %Z matching: https://github.com/python/cpython/issues/66571 # noqa: E501 def ipn_time_to_datetime(self, ipn_time: str) -> datetime: # Replace timestamp whether or not it's daylight savings time in the US ipn_time = ipn_time.replace("PDT", "-0700").replace("PST", "-0800") return datetime.strptime( ipn_time.replace("PDT", "-0700"), ipn_time, "%H:%M:%S %b %d, %Y %z" ).astimezone( timezone.utc Loading @@ -353,7 +355,7 @@ If this error persists, please reach out to us via one of the methods # that we do from webhooks, so we pick and choose the particular information from it # which will allow us to hand this info off to the rest of the donation-processing # pipeline. # (IPN messages always, and only, relate to ongoing subscriptions, so we can # (IPN messages we care about always, and only, relate to ongoing subscriptions, so we can # hardcode the message and make some other assumptions about what's in `args`.) message = "Tor\\Donation\\RecurringContributionOngoing" Loading Loading @@ -386,8 +388,8 @@ If this error persists, please reach out to us via one of the methods args = { "payment_instrument_id": "PayPal", "receive_date": timestamp, "trxn_id": param_dict["txn_id"], "handshake_id": param_dict["txn_id"], "trxn_id": param_dict["recurring_payment_id"], "handshake_id": param_dict["recurring_payment_id"], "recurring_contribution_transaction_id": param_dict["recurring_payment_id"], "currency": param_dict["mc_currency"], "total_amount": param_dict["amount"], Loading @@ -404,8 +406,17 @@ If this error persists, please reach out to us via one of the methods billing_result, "recurring", "paypal" ).inc() # Ensure that IPN messages are deduped before being handed off for processing. if await self._civi.donation_exists(message, args["trxn_id"]) is False: # Ensure that donations are deduped before being handed off for processing. # In the event that PayPal sends both an IPN message and a webhook message about the # same legacy transaction, we need to use a deduping value available to both message # types; since `txn_id` is an IPN-exclusive value, we instead use `recurring_payment_id`. # Note that this ID is unique to this transaction series, and not this individual # transaction; since recurring transactions only bill once a month, and since we only # check for duplicate transaction messages for an hour after the first message, this # value is both unique enough and broadly-available enough for our purposes. if await self._civi.donation_exists( message, args["trxn_id"] ) is False: try: await self._civi.report_donation(message, args) except ValueError: Loading Loading @@ -515,7 +526,7 @@ If this error persists, please reach out to us via one of the methods # A subscription's donation has succeeded case "PAYMENT.SALE.COMPLETED": message = "Tor\\Donation\\RecurringContributionOngoing" args["trxn_id"] = event["id"] args["trxn_id"] = event["resource"]["id"] # In the case of new Paypal subscriptions, the only ID string found both in the # post-donation success data _and_ the webhook confirming the payment went through # is the billing agreement ID. This works fine in practice, but it is the one-off Loading tordonate/static/js/script.min.js +1 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
poetry.lock +20 −56 Original line number Diff line number Diff line # This file is automatically @generated by Poetry and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "asgiref" version = "3.8.1" description = "ASGI specs, helper code, and adapters" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -19,7 +18,6 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "async-stripe" version = "5.5.0" description = "An asynchronous wrapper around Stripe's official python library." category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ Loading @@ -35,7 +33,6 @@ tornado = ">=5.1" name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -47,7 +44,6 @@ files = [ name = "beautifulsoup4" version = "4.12.3" description = "Screen-scraping library" category = "main" optional = false python-versions = ">=3.6.0" files = [ Loading @@ -69,7 +65,6 @@ lxml = ["lxml"] name = "certifi" version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" files = [ Loading @@ -81,7 +76,6 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false python-versions = ">=3.7.0" files = [ Loading Loading @@ -181,7 +175,6 @@ files = [ name = "coverage" version = "7.6.1" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading Loading @@ -266,7 +259,6 @@ toml = ["tomli"] name = "dependency-injector" version = "4.41.0" description = "Dependency injection framework for Python" category = "main" optional = false python-versions = "*" files = [ Loading Loading @@ -355,7 +347,6 @@ yaml = ["pyyaml"] name = "django" version = "4.2.15" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -376,7 +367,6 @@ bcrypt = ["bcrypt"] name = "django-bootstrap-v5" version = "1.0.11" description = "Bootstrap 5 support for Django projects" category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ Loading @@ -395,7 +385,6 @@ docs = ["m2r2 (>=0.2.5,<0.3.0)", "sphinx (>=4.4,<5.0)", "sphinx_rtd_theme (>=1.0 name = "django-jinja" version = "2.11.0" description = "Jinja2 templating language integrated in Django." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -411,7 +400,6 @@ jinja2 = ">=3" name = "django-jinja-bootstrap-form" version = "4.5.0" description = "django-jinja-bootstrap-form" category = "main" optional = false python-versions = ">=3.6" files = [ Loading @@ -427,7 +415,6 @@ django-jinja = ">=2.6.0" name = "django-prometheus" version = "2.3.1" description = "Django middlewares to monitor your application with Prometheus.io." category = "main" optional = false python-versions = "*" files = [ Loading @@ -442,7 +429,6 @@ prometheus-client = ">=0.7" name = "django-ranged-response" version = "0.2.0" description = "Modified Django FileResponse that adds Content-Range headers." category = "main" optional = false python-versions = "*" files = [ Loading @@ -456,7 +442,6 @@ django = "*" name = "django-ratelimit" version = "4.1.0" description = "Cache-based rate-limiting for Django." category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -468,7 +453,6 @@ files = [ name = "django-simple-captcha" version = "0.6.1" description = "A very simple, yet powerful, Django captcha application" category = "main" optional = false python-versions = "*" files = [] Loading @@ -477,6 +461,7 @@ develop = false [package.dependencies] Django = ">=4.2" django-ranged-response = "0.2.0" djangorestframework = ">=3.15.0" Pillow = ">=6.2.0" [package.extras] Loading @@ -485,14 +470,27 @@ test = ["testfixtures"] [package.source] type = "git" url = "https://github.com/mbi/django-simple-captcha.git" reference = "bf7fffc01b989ab411bbc29d7b27c465a0ba5289" resolved_reference = "bf7fffc01b989ab411bbc29d7b27c465a0ba5289" reference = "1c92409dd05475a94657711a048732228bf6288a" resolved_reference = "1c92409dd05475a94657711a048732228bf6288a" [[package]] name = "djangorestframework" version = "3.15.2" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.8" files = [ {file = "djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20"}, {file = "djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad"}, ] [package.dependencies] django = ">=4.2" [[package]] name = "dnspython" version = "2.6.1" description = "DNS toolkit" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -513,7 +511,6 @@ wmi = ["wmi (>=1.5.1)"] name = "email-validator" version = "2.2.0" description = "A robust email address syntax and deliverability validation library." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -529,7 +526,6 @@ idna = ">=2.0.0" name = "fakeredis" version = "2.24.1" description = "Python implementation of redis API, can be used for testing purposes." category = "dev" optional = false python-versions = "<4.0,>=3.7" files = [ Loading @@ -552,7 +548,6 @@ probabilistic = ["pyprobables (>=0.6,<0.7)"] name = "flake8" version = "6.1.0" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false python-versions = ">=3.8.1" files = [ Loading @@ -569,7 +564,6 @@ pyflakes = ">=3.1.0,<3.2.0" name = "flake8-isort" version = "6.1.1" description = "flake8 plugin that integrates isort" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -588,7 +582,6 @@ test = ["pytest"] name = "flake8-pyproject" version = "1.2.3" description = "Flake8 plug-in loading the configuration from pyproject.toml" category = "dev" optional = false python-versions = ">= 3.6" files = [ Loading @@ -605,7 +598,6 @@ dev = ["pyTest", "pyTest-cov"] name = "gunicorn" version = "20.1.0" description = "WSGI HTTP Server for UNIX" category = "dev" optional = false python-versions = ">=3.5" files = [ Loading @@ -626,7 +618,6 @@ tornado = ["tornado (>=0.2)"] name = "idna" version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false python-versions = ">=3.6" files = [ Loading @@ -638,7 +629,6 @@ files = [ name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." category = "dev" optional = false python-versions = ">=3.8.0" files = [ Loading @@ -653,7 +643,6 @@ colors = ["colorama (>=0.4.6)"] name = "jinja2" version = "3.1.4" description = "A very fast and expressive template engine." category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -671,7 +660,6 @@ i18n = ["Babel (>=2.7)"] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false python-versions = ">=3.7" files = [ Loading Loading @@ -741,7 +729,6 @@ files = [ name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = ">=3.6" files = [ Loading @@ -753,7 +740,6 @@ files = [ name = "mypy" version = "1.11.2" description = "Optional static typing for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading Loading @@ -800,7 +786,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false python-versions = ">=3.5" files = [ Loading @@ -812,7 +797,6 @@ files = [ name = "pillow" version = "10.4.0" description = "Python Imaging Library (Fork)" category = "main" optional = false python-versions = ">=3.8" files = [ Loading Loading @@ -910,7 +894,6 @@ xmp = ["defusedxml"] name = "prometheus-client" version = "0.20.0" description = "Python client for the Prometheus monitoring system." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -925,7 +908,6 @@ twisted = ["twisted"] name = "pycodestyle" version = "2.11.1" description = "Python style guide checker" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -937,7 +919,6 @@ files = [ name = "pyflakes" version = "3.1.0" description = "passive checker of Python programs" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -949,7 +930,6 @@ files = [ name = "python-dotenv" version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -964,7 +944,6 @@ cli = ["click (>=5.0)"] name = "redis" version = "5.0.8" description = "Python client for Redis database and key-value store" category = "main" optional = false python-versions = ">=3.7" files = [ Loading @@ -983,7 +962,6 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "requests" version = "2.32.3" description = "Python HTTP for Humans." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1005,7 +983,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-mock" version = "1.12.1" description = "Mock out responses from the requests package" category = "dev" optional = false python-versions = ">=3.5" files = [ Loading @@ -1023,7 +1000,6 @@ fixture = ["fixtures"] name = "setuptools" version = "74.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -1038,13 +1014,12 @@ cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.11.0,<1.12.0)", "pytest-mypy"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ Loading @@ -1056,7 +1031,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" category = "dev" optional = false python-versions = "*" files = [ Loading @@ -1068,7 +1042,6 @@ files = [ name = "soupsieve" version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1080,7 +1053,6 @@ files = [ name = "sqlparse" version = "0.5.1" description = "A non-validating SQL parser." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1096,7 +1068,6 @@ doc = ["sphinx"] name = "stripe" version = "5.5.0" description = "Python bindings for the Stripe API" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ Loading @@ -1111,7 +1082,6 @@ requests = {version = ">=2.20", markers = "python_version >= \"3.0\""} name = "tomli" version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false python-versions = ">=3.7" files = [ Loading @@ -1123,7 +1093,6 @@ files = [ name = "tornado" version = "6.4.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1144,7 +1113,6 @@ files = [ name = "types-requests" version = "2.32.0.20240712" description = "Typing stubs for requests" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1159,7 +1127,6 @@ urllib3 = ">=2" name = "types-stripe" version = "3.5.2.20240106" description = "Typing stubs for stripe" category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1171,7 +1138,6 @@ files = [ name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" category = "dev" optional = false python-versions = ">=3.8" files = [ Loading @@ -1183,7 +1149,6 @@ files = [ name = "tzdata" version = "2024.1" description = "Provider of IANA time zone data" category = "main" optional = false python-versions = ">=2" files = [ Loading @@ -1195,7 +1160,6 @@ files = [ name = "urllib3" version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=3.8" files = [ Loading @@ -1212,4 +1176,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.11" content-hash = "aa40551da0d21287e2177518c6f023f2e62ee6ddf2c75df8c25addf5760d51de" content-hash = "da05afb7869c76f57a76c97e157e76b748605e6854067eee7bbf5888932f56fb"
pyproject.toml +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.11" Django = "^4.2.4" django-simple-captcha = { git = "https://github.com/mbi/django-simple-captcha.git", rev = "bf7fffc01b989ab411bbc29d7b27c465a0ba5289" } django-simple-captcha = { git = "https://github.com/mbi/django-simple-captcha.git", rev = "1c92409dd05475a94657711a048732228bf6288a" } django-bootstrap-v5 = "^1.0.11" django-jinja = "^2.10.2" django-jinja-bootstrap-form = "^4.5.0" Loading
static/js/script.js +3 −3 Original line number Diff line number Diff line Loading @@ -61,12 +61,12 @@ dTor.init = function () { $("form.was-validated").removeClass("was-validated"); dTor.refreshCaptcha(); const messageContainer = $("#result-message"); messageContainer.html(message).removeClass("hidden"); messageContainer.text(message).removeClass("hidden"); }; this.hidePaymentError = function() { const messageContainer = $("#result-message"); messageContainer.html("").addClass("hidden"); messageContainer.text("").addClass("hidden"); } this.handleFormErrors = function (errors) { Loading Loading @@ -118,7 +118,7 @@ dTor.init = function () { this.validateElement = function (el) { if (!el.checkValidity() || $(el).val() == null) { $(el).siblings(".invalid-feedback").html(el.validationMessage); $(el).siblings(".invalid-feedback").text(el.validationMessage); $(el).addClass("is-invalid"); } else { $(el).removeClass("is-invalid"); Loading
tordonate/paypal/controller.py +18 −7 Original line number Diff line number Diff line Loading @@ -331,8 +331,10 @@ If this error persists, please reach out to us via one of the methods # IPN timestamp info: https://developer.paypal.com/api/nvp-soap/ipn/IPNandPDTVariables/#payment-information # noqa: E501 # Relevant Python Github issue regarding strptime's %Z matching: https://github.com/python/cpython/issues/66571 # noqa: E501 def ipn_time_to_datetime(self, ipn_time: str) -> datetime: # Replace timestamp whether or not it's daylight savings time in the US ipn_time = ipn_time.replace("PDT", "-0700").replace("PST", "-0800") return datetime.strptime( ipn_time.replace("PDT", "-0700"), ipn_time, "%H:%M:%S %b %d, %Y %z" ).astimezone( timezone.utc Loading @@ -353,7 +355,7 @@ If this error persists, please reach out to us via one of the methods # that we do from webhooks, so we pick and choose the particular information from it # which will allow us to hand this info off to the rest of the donation-processing # pipeline. # (IPN messages always, and only, relate to ongoing subscriptions, so we can # (IPN messages we care about always, and only, relate to ongoing subscriptions, so we can # hardcode the message and make some other assumptions about what's in `args`.) message = "Tor\\Donation\\RecurringContributionOngoing" Loading Loading @@ -386,8 +388,8 @@ If this error persists, please reach out to us via one of the methods args = { "payment_instrument_id": "PayPal", "receive_date": timestamp, "trxn_id": param_dict["txn_id"], "handshake_id": param_dict["txn_id"], "trxn_id": param_dict["recurring_payment_id"], "handshake_id": param_dict["recurring_payment_id"], "recurring_contribution_transaction_id": param_dict["recurring_payment_id"], "currency": param_dict["mc_currency"], "total_amount": param_dict["amount"], Loading @@ -404,8 +406,17 @@ If this error persists, please reach out to us via one of the methods billing_result, "recurring", "paypal" ).inc() # Ensure that IPN messages are deduped before being handed off for processing. if await self._civi.donation_exists(message, args["trxn_id"]) is False: # Ensure that donations are deduped before being handed off for processing. # In the event that PayPal sends both an IPN message and a webhook message about the # same legacy transaction, we need to use a deduping value available to both message # types; since `txn_id` is an IPN-exclusive value, we instead use `recurring_payment_id`. # Note that this ID is unique to this transaction series, and not this individual # transaction; since recurring transactions only bill once a month, and since we only # check for duplicate transaction messages for an hour after the first message, this # value is both unique enough and broadly-available enough for our purposes. if await self._civi.donation_exists( message, args["trxn_id"] ) is False: try: await self._civi.report_donation(message, args) except ValueError: Loading Loading @@ -515,7 +526,7 @@ If this error persists, please reach out to us via one of the methods # A subscription's donation has succeeded case "PAYMENT.SALE.COMPLETED": message = "Tor\\Donation\\RecurringContributionOngoing" args["trxn_id"] = event["id"] args["trxn_id"] = event["resource"]["id"] # In the case of new Paypal subscriptions, the only ID string found both in the # post-donation success data _and_ the webhook confirming the payment went through # is the billing agreement ID. This works fine in practice, but it is the one-off Loading
tordonate/static/js/script.min.js +1 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes