Compare commits

...

10 Commits

@ -1,39 +1,39 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIG0zCCBLugAwIBAgIJAOOv2BdszSOVMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD MIIG0zCCBLugAwIBAgIUEEze40yQlf+q4ncb8IuqnOd/hNQwDQYJKoZIhvcNAQEL
VQQGEwJGUjERMA8GA1UEBxMIU29tZUNpdHkxHzAdBgNVBAoTFkNvZ25pdGl2ZSBD BQAwgZkxCzAJBgNVBAYTAkZSMR8wHQYDVQQKExZDb2duaXRpdmUgQ3J5cHRvZ3Jh
cnlwdG9ncmFwaHkxEzARBgNVBAsTCkNDcnlwdG9WUE4xEzARBgNVBAMTCkNDcnlw cGh5MRMwEQYDVQQLEwpDQ3J5cHRvVlBOMR4wHAYDVQQDExVDQ3J5cHRvVlBOIFJv
dG9WUE4xEzARBgNVBCkTCkNDcnlwdG9WUE4xHzAdBgkqhkiG9w0BCQEWEGNlcnRA b3QgdjIgQ0ExEzARBgNVBCkTCkNDcnlwdG9WUE4xHzAdBgkqhkiG9w0BCQEWEGNl
Y2NyeXB0by5vcmcwHhcNMTMwODEzMTgxOTQ4WhcNMjMwODExMTgxOTQ4WjCBoTEL cnRAY2NyeXB0by5vcmcwIBcNMjIwNDI1MTU1NTE4WhgPMjEyMjA0MDExNTU1MTha
MAkGA1UEBhMCRlIxETAPBgNVBAcTCFNvbWVDaXR5MR8wHQYDVQQKExZDb2duaXRp MIGZMQswCQYDVQQGEwJGUjEfMB0GA1UEChMWQ29nbml0aXZlIENyeXB0b2dyYXBo
dmUgQ3J5cHRvZ3JhcGh5MRMwEQYDVQQLEwpDQ3J5cHRvVlBOMRMwEQYDVQQDEwpD eTETMBEGA1UECxMKQ0NyeXB0b1ZQTjEeMBwGA1UEAxMVQ0NyeXB0b1ZQTiBSb290
Q3J5cHRvVlBOMRMwEQYDVQQpEwpDQ3J5cHRvVlBOMR8wHQYJKoZIhvcNAQkBFhBj IHYyIENBMRMwEQYDVQQpEwpDQ3J5cHRvVlBOMR8wHQYJKoZIhvcNAQkBFhBjZXJ0
ZXJ0QGNjcnlwdG8ub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA QGNjcnlwdG8ub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA12zS
xvkZj62nUvSjEPs1qBokLd8bBpBlLj6RGgJpfPqS/kKF0s1HpcYZynIcqP6Dw/Pi Z0Y3poiQLgmW6yWBOcyGFsDkBqalVKAMpzioW6ph91MExfwTnsUtZ1V/rJ74RGCi
LFcTE1STzgFfcEdKLmZAH+JCFVpc9mRTXEifouBk+2j3MG9+j2GTXHCK5FMkcJWQ c8vF97/frZg7XtmFavdLJkq9NMDLtJ4xHapBjtr6AP8pkWeo4KLfN4YiujUEYMI/
o4YihO2UOLz8qz4yn3dmy0zP1UmqxB2SayYXhwT2+pDSTkBCP6YtRURVVNIVRM7A lzugASzdMDVVA8cUitE5jU+qWZKcSYGHZOvY/6EscyvhdtyfSs9+jkzgQdAL1YLw
72hBUJ2dUgKHMTsBJSQj/11rRJ6wW6yUt0NtEcDUbdgrq0BibHq8zzCkl3vGl20M GcXJe5yocl1Nt+6XnnQcdvvVmmEy1s1AoVW73721qEh5vIXjnRr0SEeqAlD1JiuS
2UCXPNKavP1aapoDGWLSxZgJ9nkFUfWbjWjHuuBw8cjQ7OV7SLiBXqLNJdcCshDA fN09SoMSHawi2g+LiOZY0IoIEMzCWkcbEBjQszcvZyMiR9/vm19x0T2VycHUBgkv
OlwaPS4atao73rliE8bWAsGiwJZ+WXnGNJAr/6BwEtOizc6hr92S8lHOrlEWz3/F VZgMdryiLFJ+CiVydaMSvUN6IootUkzF/xe3EhQEToWz/MM/YTFI8spVR4tXzxgw
h2+L/GI97KMM+pfxlTd8j4dbBpDIXv2vlpYOQ97EbYSbWv7fmYZ2BxxgljATBPfA f91BPhENuMVC+JtUfo6q5x9XFlmJT81SFTgW+lo7dBbnL3yh3yIcN5yMEdBJty9k
hA/y7GEfTodC/mkyZO8R2joBxcbQRu7AjsL30AOiE0GepUQNqhlbhEePvm28C9Rn YVxHGGT6jx5CfGPP4J8/70MhrDG22+qQ28b/SYTOdmzimKMdsPnqku2TGJoxXluf
OHm4zaqQLo3BJzlP23N9sn4cMZYMiPnx+eCDv+UW7Y+xHVz0GSjlO1IkZ5lTu2fR ROlN1iyk+1Ry4AexzpbB2I0Apd1n+6udo2Vv+atTeV7sE7ajxUhyzfZj1kIARUi0
IbONfLYDGcByOBaLmo3oD60grw552COTAYDMlu2h8zQV0gPhJziO/txDapoBuNeX T3ZNTsdvqyrfTWCNYggjXOPpPGOk3bcX6jUAXZ4fjsVg9i13BNghso2NVcepGYMZ
XUdzzp1l6GFTsqIKs6ATleJ4n/S4OQe/kicZkCdYZ3kCAwEAAaOCAQowggEGMB0G eYSfaSmzY7A85Qa4xwXuN2FxbXPsFsXYtuPimpMCAwEAAaOCAQ0wggEJMB0GA1Ud
A1UdDgQWBBTWsE0h2/8fw8SbrhvXny8aBL/KTTCB1gYDVR0jBIHOMIHLgBTWsE0h DgQWBBQz/6L/JOGHHSLYUbnhfVRLGyUxaTCB2QYDVR0jBIHRMIHOgBQz/6L/JOGH
2/8fw8SbrhvXny8aBL/KTaGBp6SBpDCBoTELMAkGA1UEBhMCRlIxETAPBgNVBAcT HSLYUbnhfVRLGyUxaaGBn6SBnDCBmTELMAkGA1UEBhMCRlIxHzAdBgNVBAoTFkNv
CFNvbWVDaXR5MR8wHQYDVQQKExZDb2duaXRpdmUgQ3J5cHRvZ3JhcGh5MRMwEQYD Z25pdGl2ZSBDcnlwdG9ncmFwaHkxEzARBgNVBAsTCkNDcnlwdG9WUE4xHjAcBgNV
VQQLEwpDQ3J5cHRvVlBOMRMwEQYDVQQDEwpDQ3J5cHRvVlBOMRMwEQYDVQQpEwpD BAMTFUNDcnlwdG9WUE4gUm9vdCB2MiBDQTETMBEGA1UEKRMKQ0NyeXB0b1ZQTjEf
Q3J5cHRvVlBOMR8wHQYJKoZIhvcNAQkBFhBjZXJ0QGNjcnlwdG8ub3JnggkA46/Y MB0GCSqGSIb3DQEJARYQY2VydEBjY3J5cHRvLm9yZ4IUEEze40yQlf+q4ncb8Iuq
F2zNI5UwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAMQsLBf8TPFkh nOd/hNQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAG/F9/E6aq04M
/cnsh+E2N5YCqoeiYwLfPlqo3DwVaDoD8w5NovbIj+O6Z31FkTbt2Zotky6BQMCz TUNUUfAGh4MTgEXd+DnMEUOoSk30mhqbQ/a7FafHn3WREvqlnIfiE7Ysi3DGjGQX
5wfuPa1WPuU2kARqS+4LA8FOd1tH4+xqGE6lgkqQuKGJEhi4J4wBg0yKvS4GxZ0+ YicooaUYdB4oUy2o853wvxTDinlt8O766VdCl3b3lgHDWYOkwGPJ4uG+xQuBm4XG
ZXw+fWZSGDPR8WlKVfAR6DEuPIgJqIo0hIWbMgKsmqDzxevWg+Y8C9X0VjLwaSX+ S4sEZukvE7hfxOhHQWZlkwvg+x34M3oDogWgInFQveCQnIZ9Dz3dF2eCvPtdA8IV
dcC9N+ztYFKkzP4yOba8vFjYBmAYzaxwloUmm+iaTD/jrik9kqjd6grNh8bQa/0N I4S5KtM/DLXLhRWbmuc3vVE2c6l0y1gtLeX8s1Yw2B0748cinNH7tobWJ71b1sYL
hzoa0UL8qgnorusvzo85B/I+cavS37djAeoZ1Oilerp39HS5yjvtbI/ijKW6Wp0l WMvX0G6uL+q67zdZmD12lnjzNWKKQHPVVD+L9yFhn1QAEExrbGzmaKUIGwZmxtD1
aYCQ6e9f6Ka9cMfVwDJ+aow3rp0MJG0ilP+mS+ouE/R4tnAfVXrlh5X7tsGanByu H48YOcx2UgeAfeUPEfVfKBVvNrG68DizlM4iCmZ5T/L7sqDtlHYnbGigbMSspNdM
LtXIbRrLGcCmmNLtdZ2lRVi3BRRKQu5G/6WkvjslBU27CcvKnTtT7FmtKg9564rB IQSpsyjKtq9hQwu+3BTkyg6yiWHuS+IxHf7ngSf8hxX/3caz3YX3AlruE2mRLJ+x
NCRawVf3veelwmVdnmkKd6Ka05ymJrm3ZU03+41ilSiqecFRFqz/+urdYkmynJtq AVfSxf+jfDWyAh5gogx3CrZuyBd5USab1dDllGlUUto4ozZDT9sIhRf2UV4Wvj1K
E4hNy013h6rooKnNXrMDMuTJqPTa0xJTM+74+JQwEZETSW7TdAGVrqRnJXdXn8Zi eXdWqevSgT6a6bVrtYLQqfItuhR04g3rJu7iu7sjiiE5qSgOdxBtcPy4eXbmIyo5
17Gr351BJNOBWvyk8MPBKLM24e0qX+4NykQCT8Whhj4YQ/wzvwx2ayKAfoJYd74s BCExfyI1eG4CJtnuSX/0RL/Mz9ouxXwDUKnCRh1z5BUZrsVT9hs1jR6kRk6rEmLt
9ZCg4dyZMObBjkw08am0H6W6pe9umaY= 8ssASXZQQRu3iDXj33uhMGfghoy6KGg=
-----END CERTIFICATE----- -----END CERTIFICATE-----

@ -3,7 +3,7 @@ import binascii
from collections import OrderedDict from collections import OrderedDict
from django.contrib.auth.hashers import BasePasswordHasher from django.contrib.auth.hashers import BasePasswordHasher
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
class LegacyPasswordHasher(BasePasswordHasher): class LegacyPasswordHasher(BasePasswordHasher):

@ -3,6 +3,7 @@ from django.contrib import admin
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
import django_lcore import django_lcore
import django_lcore.urls
from lambdainst import views as account_views from lambdainst import views as account_views

@ -7,12 +7,10 @@ from markdown.extensions.toc import TocExtension
from django.http import HttpResponseNotFound from django.http import HttpResponseNotFound
from django.shortcuts import render from django.shortcuts import render
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext as _, get_language from django.utils.translation import gettext as _, get_language
from django import http from django import http
from django.utils.http import is_safe_url from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.translation import ( from django.utils.translation import check_for_language
LANGUAGE_SESSION_KEY, check_for_language,
)
from django.template.loader import TemplateDoesNotExist, get_template, select_template from django.template.loader import TemplateDoesNotExist, get_template, select_template
from django.template import Template from django.template import Template
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
@ -61,17 +59,24 @@ def set_lang(request):
""" django.views.i18n.set_language() with GET """ """ django.views.i18n.set_language() with GET """
next = request.GET.get('next', request.GET.get('next')) next = request.GET.get('next', request.GET.get('next'))
if not is_safe_url(url=next, allowed_hosts={request.get_host()}): if not url_has_allowed_host_and_scheme(url=next, allowed_hosts={request.get_host()}):
next = request.META.get('HTTP_REFERER') next = request.META.get('HTTP_REFERER')
if not is_safe_url(url=next, allowed_hosts={request.get_host()}): if not url_has_allowed_host_and_scheme(url=next, allowed_hosts={request.get_host()}):
next = '/' next = '/'
response = http.HttpResponseRedirect(next) response = http.HttpResponseRedirect(next)
lang_code = request.GET.get('lang', None) lang_code = request.GET.get('lang', None)
if lang_code and check_for_language(lang_code): if lang_code and check_for_language(lang_code):
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE, response.set_cookie(
path=settings.LANGUAGE_COOKIE_PATH, settings.LANGUAGE_COOKIE_NAME,
domain=settings.LANGUAGE_COOKIE_DOMAIN) lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
secure=settings.LANGUAGE_COOKIE_SECURE,
httponly=settings.LANGUAGE_COOKIE_HTTPONLY,
samesite=settings.LANGUAGE_COOKIE_SAMESITE,
)
return response return response

@ -1,7 +1,7 @@
from django import template from django import template
from django.utils.html import format_html from django.utils.html import format_html
from downloads.models import Version, Platform from downloads.models import Version, Platform
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
register = template.Library() register = template.Library()

@ -5,7 +5,7 @@ from django.contrib import admin
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.admin import UserAdmin from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
from django.utils.html import format_html from django.utils.html import format_html
import django_lcore import django_lcore
import lcoreapi import lcoreapi
@ -43,14 +43,13 @@ class VPNUserInline(admin.StackedInline):
if not object.referrer: if not object.referrer:
return "-" return "-"
s = make_user_link(object.referrer) + " "
if object.referrer_used: if object.referrer_used:
s += _("(rewarded)") status = _("(rewarded)")
else: else:
s += _("(not rewarded)") status = _("(not rewarded)")
return s
return format_html("{} {}", make_user_link(object.referrer), status)
referrer_a.allow_tags = True
referrer_a.short_description = _("Referrer") referrer_a.short_description = _("Referrer")
def is_paid(self, object): def is_paid(self, object):
@ -81,7 +80,7 @@ class UserAdmin(UserAdmin):
), ),
) )
readonly_fields = ("last_login", "date_joined", "links") readonly_fields = ("last_login", "date_joined", "links")
actions = (django_lcore.core_sync_action,) actions = (django_lcore.admin.core_sync_action,)
def is_paid(self, object): def is_paid(self, object):
return object.vpnuser.is_paid return object.vpnuser.is_paid

@ -1,7 +1,7 @@
import base64 import base64
from django import forms from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe

@ -2,7 +2,7 @@ import random
from datetime import timedelta from datetime import timedelta
from django.db import models, IntegrityError from django.db import models, IntegrityError
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
from django.utils import timezone from django.utils import timezone
from django_lcore.core import ( from django_lcore.core import (
LcoreUserProfileMethods, LcoreUserProfileMethods,
@ -65,13 +65,6 @@ class VPNUser(models.Model, BaseSubUser, LcoreUserProfileMethods):
self.referrer_used = True self.referrer_used = True
self.save() self.save()
@property
def subscr_is_failing(self):
margin = timedelta(hours=24)
if self.expiration < timezone.now() + margin:
return True
return False
def lcore_sync(self): def lcore_sync(self):
if VPN_AUTH_STORAGE == "inst": if VPN_AUTH_STORAGE == "inst":
return return

@ -1,6 +1,6 @@
import json import json
import uuid import uuid
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
from django.conf import settings from django.conf import settings

@ -1,4 +1,4 @@
from django.utils.translation import ugettext, ungettext from django.utils.translation import gettext, ngettext
from django.template import Library from django.template import Library
from django.utils.html import avoid_wrapping from django.utils.html import avoid_wrapping
from django.utils import formats from django.utils import formats
@ -11,7 +11,7 @@ def bwformat(bps):
try: try:
bps = float(bps) bps = float(bps)
except (TypeError, ValueError, UnicodeDecodeError): except (TypeError, ValueError, UnicodeDecodeError):
value = ungettext("%(bw)d bps", "%(bw)d bps", 0) % {"bw": 0} value = ngettext("%(bw)d bps", "%(bw)d bps", 0) % {"bw": 0}
return avoid_wrapping(value) return avoid_wrapping(value)
filesize_number_format = lambda value: formats.number_format(round(value, 1), -1) filesize_number_format = lambda value: formats.number_format(round(value, 1), -1)
@ -23,16 +23,16 @@ def bwformat(bps):
P = 1 * 10 ** 15 P = 1 * 10 ** 15
if bps < K: if bps < K:
value = ungettext("%(size)d bps", "%(size)d bps", bps) % {"size": bps} value = ngettext("%(size)d bps", "%(size)d bps", bps) % {"size": bps}
elif bps < M: elif bps < M:
value = ugettext("%s Kbps") % filesize_number_format(bps / K) value = gettext("%s Kbps") % filesize_number_format(bps / K)
elif bps < G: elif bps < G:
value = ugettext("%s Mbps") % filesize_number_format(bps / M) value = gettext("%s Mbps") % filesize_number_format(bps / M)
elif bps < T: elif bps < T:
value = ugettext("%s Gbps") % filesize_number_format(bps / G) value = gettext("%s Gbps") % filesize_number_format(bps / G)
elif bps < P: elif bps < P:
value = ugettext("%s Tbps") % filesize_number_format(bps / T) value = gettext("%s Tbps") % filesize_number_format(bps / T)
else: else:
value = ugettext("%s Pbps") % filesize_number_format(bps / P) value = gettext("%s Pbps") % filesize_number_format(bps / P)
return avoid_wrapping(value) return avoid_wrapping(value)

@ -22,7 +22,7 @@ from django.http import (
) )
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django_countries import countries from django_countries import countries
import django_lcore import django_lcore
@ -195,7 +195,8 @@ def index(request):
context = dict( context = dict(
title=_("Account"), title=_("Account"),
ref_url=ref_url, ref_url=ref_url,
subscription=request.user.vpnuser.get_subscription(), active_subscription=request.user.vpnuser.get_active_subscription(),
last_subscription=request.user.vpnuser.get_last_subscription(),
backends=sorted(ACTIVE_BACKENDS.values(), key=lambda x: x.backend_display_name), backends=sorted(ACTIVE_BACKENDS.values(), key=lambda x: x.backend_display_name),
subscr_backends=sorted( subscr_backends=sorted(
(b for b in ACTIVE_BACKENDS.values() if b.backend_has_recurring), (b for b in ACTIVE_BACKENDS.values() if b.backend_has_recurring),

@ -5,7 +5,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: unnamed project\n" "Project-Id-Version: unnamed project\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-09-14 20:19+0000\n" "POT-Creation-Date: 2022-05-19 19:04+0000\n"
"PO-Revision-Date: 2021-09-14 22:21+0200\n" "PO-Revision-Date: 2021-09-14 22:21+0200\n"
"Last-Translator: alice <alice@ccrypto.org>\n" "Last-Translator: alice <alice@ccrypto.org>\n"
"Language-Team: French <alice@ccrypto.org>\n" "Language-Team: French <alice@ccrypto.org>\n"
@ -30,7 +30,7 @@ msgstr ""
msgid "hash" msgid "hash"
msgstr "" msgstr ""
#: ccvpn/views.py:56 #: ccvpn/views.py:54
msgid "Live Chat" msgid "Live Chat"
msgstr "Chat Live" msgstr "Chat Live"
@ -38,27 +38,27 @@ msgstr "Chat Live"
msgid "Download {} v{}" msgid "Download {} v{}"
msgstr "Télécharger {} v{}" msgstr "Télécharger {} v{}"
#: lambdainst/admin.py:48 #: lambdainst/admin.py:47
msgid "(rewarded)" msgid "(rewarded)"
msgstr "" msgstr ""
#: lambdainst/admin.py:50 #: lambdainst/admin.py:49
msgid "(not rewarded)" msgid "(not rewarded)"
msgstr "" msgstr ""
#: lambdainst/admin.py:54 #: lambdainst/admin.py:53
msgid "Referrer" msgid "Referrer"
msgstr "" msgstr ""
#: lambdainst/admin.py:60 lambdainst/admin.py:90 #: lambdainst/admin.py:59 lambdainst/admin.py:89
msgid "Is paid?" msgid "Is paid?"
msgstr "Est payé?" msgstr "Est payé?"
#: lambdainst/admin.py:69 #: lambdainst/admin.py:68
msgid "Important dates" msgid "Important dates"
msgstr "Dates importantes" msgstr "Dates importantes"
#: lambdainst/admin.py:71 #: lambdainst/admin.py:70
msgid "Permissions" msgid "Permissions"
msgstr "Permissions" msgstr "Permissions"
@ -287,14 +287,6 @@ msgstr ""
msgid "Other" msgid "Other"
msgstr "Autre" msgstr "Autre"
#: templates/base_help.html:73
msgid "Advanced"
msgstr "Avancé"
#: templates/base_help.html:77
msgid "Tor"
msgstr "Tor"
#: templates/ccvpn/chat.html:9 #: templates/ccvpn/chat.html:9
#, python-format #, python-format
msgid "" msgid ""
@ -391,7 +383,28 @@ msgstr "Payez par carte, PayPal, ou 40+ cryptomonnaies."
msgid "Sign up & try for a week for free" msgid "Sign up & try for a week for free"
msgstr "Créez un compte et essayez gratuitement" msgstr "Créez un compte et essayez gratuitement"
#: templates/ccvpn/index.html:74 #: templates/ccvpn/index.html:66
msgid "No CC required, 3€/month after 7 days"
msgstr "Abonnez-vous pour 3€/mois après 7 jours"
#: templates/ccvpn/index.html:71
msgid "CCrypto is a non-profit organization."
msgstr "CCrypto est une association à but non lucratif."
#: templates/ccvpn/index.html:72
msgid ""
"As such, we pledge that we will never sell your personal information, "
"exploit your trust or data, or get acquired by a company without such "
"boundaries. Your payments will go exclusively towards funding our services "
"and staff, or to other non-profits."
msgstr ""
"À ce titre, nous promettons ne jamais vendre vos données personnelles, "
"exploiter votre traffic ou votre confiance, ou laisser une entreprise sans "
"de tels principes nous racheter. Vos paiements seront exclusivement utilisés "
"pour financer notre service et rémunérer notre équipe, ou reversés à "
"d'autres associations."
#: templates/ccvpn/index.html:84
msgid "more on our infrastructure" msgid "more on our infrastructure"
msgstr "plus sur notre infrastructure" msgstr "plus sur notre infrastructure"
@ -477,93 +490,99 @@ msgstr "ACTIF"
msgid "INACTIVE" msgid "INACTIVE"
msgstr "INACTIF" msgstr "INACTIF"
#: templates/lambdainst/account.html:34 templates/lambdainst/account.html:73 #: templates/lambdainst/account.html:34 templates/lambdainst/account.html:77
msgid "Subscription" msgid "Subscription"
msgstr "Abonnement" msgstr "Abonnement"
#: templates/lambdainst/account.html:37 #: templates/lambdainst/account.html:37
#, python-format #, python-format
msgid ""
"<b>FAILING</b> since %(since)s. (%(backend)s)<br /> Please cancel and "
"subscribe again if you need to switch to another payment method."
msgstr ""
"<b>ERREUR</b> depuis %(since)s. (%(backend)s)<br />\n"
"Veuillez annuler et vous réabonner pour changer de méthode ou carte de "
"paiement."
#: templates/lambdainst/account.html:42
#, python-format
msgid "<b>ACTIVE</b>. Renews on %(until)s via %(backend)s." msgid "<b>ACTIVE</b>. Renews on %(until)s via %(backend)s."
msgstr "<b>ACTIF</b>. Renouvellement: %(until)s via %(backend)s" msgstr "<b>ACTIF</b>. Renouvellement: %(until)s via %(backend)s"
#: templates/lambdainst/account.html:45 #: templates/lambdainst/account.html:40
msgid "cancel" msgid "cancel"
msgstr "annuler" msgstr "annuler"
#: templates/lambdainst/account.html:53 #: templates/lambdainst/account.html:43
msgid "<b>CANCELLED</b>. You can subscribe again below."
msgstr "<b>ANNULLÉ</b>. Vous pouvez vous réabonnez plus bas."
#: templates/lambdainst/account.html:45
msgid "<b>Last payment failed</b>, likely because your card expired."
msgstr "<b>Échec du dernier paiement</b>, votre carte a probablement expirée."
#: templates/lambdainst/account.html:46
msgid "You can update your subscription below."
msgstr "Vous pouvez mettre à jour votre souscription plus bas."
#: templates/lambdainst/account.html:48
msgid "Pending"
msgstr "En attente"
#: templates/lambdainst/account.html:57
msgid "Expiration" msgid "Expiration"
msgstr "Expiration" msgstr "Expiration"
#: templates/lambdainst/account.html:57 #: templates/lambdainst/account.html:61
#, python-format #, python-format
msgid "(%(left)s left)" msgid "(%(left)s left)"
msgstr "(%(left)s restant)" msgstr "(%(left)s restant)"
#: templates/lambdainst/account.html:81 #: templates/lambdainst/account.html:85
msgid "Pay every" msgid "Pay every"
msgstr "Payer tous les" msgstr "Payer tous les"
#: templates/lambdainst/account.html:83 templates/lambdainst/account.html:84 #: templates/lambdainst/account.html:87 templates/lambdainst/account.html:88
#: templates/lambdainst/account.html:85 templates/lambdainst/account.html:122 #: templates/lambdainst/account.html:89 templates/lambdainst/account.html:126
#: templates/lambdainst/account.html:123 templates/lambdainst/account.html:124 #: templates/lambdainst/account.html:127 templates/lambdainst/account.html:128
msgid "months" msgid "months"
msgstr "mois" msgstr "mois"
#: templates/lambdainst/account.html:90 templates/lambdainst/account.html:129 #: templates/lambdainst/account.html:94 templates/lambdainst/account.html:133
msgid "by" msgid "by"
msgstr "par" msgstr "par"
#: templates/lambdainst/account.html:102 #: templates/lambdainst/account.html:106
msgid "Subscribe" msgid "Subscribe"
msgstr "S'abonner" msgstr "S'abonner"
#: templates/lambdainst/account.html:104 #: templates/lambdainst/account.html:108
msgid "You can cancel the recurring payment at any time." msgid "You can cancel the recurring payment at any time."
msgstr "Vous pouvez annuler le paiement récurrent à n'importe quel moment." msgstr "Vous pouvez annuler le paiement récurrent à n'importe quel moment."
#: templates/lambdainst/account.html:111 #: templates/lambdainst/account.html:115
msgid "One-time payment" msgid "One-time payment"
msgstr "Paiement ponctuel" msgstr "Paiement ponctuel"
#: templates/lambdainst/account.html:119 #: templates/lambdainst/account.html:123
msgid "Add" msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
#: templates/lambdainst/account.html:121 #: templates/lambdainst/account.html:125
msgid "month" msgid "month"
msgstr "mois" msgstr "mois"
#: templates/lambdainst/account.html:141 #: templates/lambdainst/account.html:145
msgid "Buy Now" msgid "Buy Now"
msgstr "Payer" msgstr "Payer"
#: templates/lambdainst/account.html:143 #: templates/lambdainst/account.html:147
msgid "If you still have time, the first payment will be delayed." msgid "If you still have time, the first payment will be delayed."
msgstr "S'il vous reste du temps, le premier paiement sera reporté." msgstr "S'il vous reste du temps, le premier paiement sera reporté."
#: templates/lambdainst/account.html:150 #: templates/lambdainst/account.html:154
msgid "Coupon" msgid "Coupon"
msgstr "Coupon" msgstr "Coupon"
#: templates/lambdainst/account.html:157 #: templates/lambdainst/account.html:161
msgid "Code" msgid "Code"
msgstr "Code" msgstr "Code"
#: templates/lambdainst/account.html:163 #: templates/lambdainst/account.html:167
msgid "Use" msgid "Use"
msgstr "Utiliser" msgstr "Utiliser"
#: templates/lambdainst/account.html:165 #: templates/lambdainst/account.html:169
msgid "" msgid ""
"Our coupons are alphanumeric codes that give you a fixed duration of VPN " "Our coupons are alphanumeric codes that give you a fixed duration of VPN "
"access." "access."
@ -571,11 +590,11 @@ msgstr ""
"Nos coupons sont des codes alphanumériques qui donnent une durée fixe " "Nos coupons sont des codes alphanumériques qui donnent une durée fixe "
"d'accès au VPN." "d'accès au VPN."
#: templates/lambdainst/account.html:166 #: templates/lambdainst/account.html:170
msgid "They can be single or multi use." msgid "They can be single or multi use."
msgstr "À usage unique ou multiple." msgstr "À usage unique ou multiple."
#: templates/lambdainst/account.html:178 #: templates/lambdainst/account.html:182
msgid "" msgid ""
"Please recommend us to your friends and on social media! We do not advertise " "Please recommend us to your friends and on social media! We do not advertise "
"and rely on you to help us grow and improve our services." "and rely on you to help us grow and improve our services."
@ -583,7 +602,7 @@ msgstr ""
"Recommandez-nous à vos amis et sur les réseaux sociaux! Nous ne faisons pas " "Recommandez-nous à vos amis et sur les réseaux sociaux! Nous ne faisons pas "
"de publicité et comptons sur vous pour nous aider à améliorer nos services." "de publicité et comptons sur vous pour nous aider à améliorer nos services."
#: templates/lambdainst/account.html:183 #: templates/lambdainst/account.html:187
msgid "" msgid ""
"Every subscription through this link will grant you 1&nbsp;month of VPN " "Every subscription through this link will grant you 1&nbsp;month of VPN "
"access:" "access:"
@ -1001,19 +1020,19 @@ msgstr "Importez la configuration dans WireGuard."
#: templates/pages/_install_base.html:45 #: templates/pages/_install_base.html:45
msgid "" msgid ""
"On Android and iOS, open the app and scan the <a href=\"/account/wireguard" "On Android and iOS, open the app and scan the <a href=\"/account/"
"\">QR code from your account</a>" "wireguard\">QR code from your account</a>"
msgstr "" msgstr ""
"Sur Android et iOS, ouvrez l'app et scannez le <a href=\"/account/wireguard" "Sur Android et iOS, ouvrez l'app et scannez le <a href=\"/account/"
"\">code QR disponible dans votre compte</a>" "wireguard\">code QR disponible dans votre compte</a>"
#: templates/pages/_install_base.html:51 #: templates/pages/_install_base.html:51
msgid "" msgid ""
"On Windows, mac OS and Linux, import a configuration file <a href=\"/account/" "On Windows, mac OS and Linux, import a configuration file <a href=\"/account/"
"wireguard\">downloaded from your account</a>" "wireguard\">downloaded from your account</a>"
msgstr "" msgstr ""
"Sur Windows, mac OS, et Linux, importez le fichier de configuration <a href=" "Sur Windows, mac OS, et Linux, importez le fichier de configuration <a "
"\"/account/wireguard\">à télécharger dans votre compte</a>" "href=\"/account/wireguard\">à télécharger dans votre compte</a>"
#: templates/pages/_install_base.html:61 #: templates/pages/_install_base.html:61
#: templates/pages/install-android.html:31 #: templates/pages/install-android.html:31
@ -1071,8 +1090,8 @@ msgstr ""
#: templates/pages/help.html:29 #: templates/pages/help.html:29
msgid "" msgid ""
"If you need to contact us, the fastest and most secure way is to use <a href=" "If you need to contact us, the fastest and most secure way is to use <a "
"\"/tickets/\"><em>Tickets</em></a> for technical or billing issues." "href=\"/tickets/\"><em>Tickets</em></a> for technical or billing issues."
msgstr "" msgstr ""
"Si vous devez nous contacter, le moyen le plus rapide est <a href=\"/tickets/" "Si vous devez nous contacter, le moyen le plus rapide est <a href=\"/tickets/"
"\"><em>les tickets</em></a> pour les questions technique en rapport à votre " "\"><em>les tickets</em></a> pour les questions technique en rapport à votre "
@ -1269,8 +1288,8 @@ msgid ""
"Pick one in the <a href=\"%(url)s\">server list</a>, or <code>%(gw)s</code> " "Pick one in the <a href=\"%(url)s\">server list</a>, or <code>%(gw)s</code> "
"for a random server." "for a random server."
msgstr "" msgstr ""
"Choisissez dans la <a href=\"%(url)s\">liste de serveurs</a> ou <code>" "Choisissez dans la <a href=\"%(url)s\">liste de serveurs</a> ou "
"%(gw)s</code> pour un serveur aléatoire." "<code>%(gw)s</code> pour un serveur aléatoire."
#: templates/pages/install-linux.html:79 #: templates/pages/install-linux.html:79
msgid "Type" msgid "Type"
@ -1593,8 +1612,8 @@ msgstr ""
#: templates/pages/install-windows.html:84 #: templates/pages/install-windows.html:84
msgid "" msgid ""
"In <a href=\"/account/config\">your account</a>, download a .ovpn " "In <a href=\"/account/config\">your account</a>, download a .ovpn "
"configuration file, and copy it into <code>C:\\Program Files\\OpenVPN\\config" "configuration file, and copy it into <code>C:\\Program "
"\\</code>." "Files\\OpenVPN\\config\\</code>."
msgstr "" msgstr ""
"Dans <a href=\"/account/config\">votre compte</a>, téléchargez le fichier ." "Dans <a href=\"/account/config\">votre compte</a>, téléchargez le fichier ."
"ovpn et copiez le dans <code>C:\\Program Files\\OpenVPN\\config\\</code>." "ovpn et copiez le dans <code>C:\\Program Files\\OpenVPN\\config\\</code>."
@ -1673,6 +1692,10 @@ msgstr ""
"Voudriez-vous nous dire pourquoi, ou laisser un retour pour nous permettre " "Voudriez-vous nous dire pourquoi, ou laisser un retour pour nous permettre "
"d'améliorer notre service ? C'est optionel." "d'améliorer notre service ? C'est optionel."
#: templates/payments/cancel_subscr.html:27
msgid "You do not have any active subscription to cancel."
msgstr "Vous n'avez pas d'abonnement à annuller."
#: templates/payments/order-pay.html:5 templates/payments/success.html:12 #: templates/payments/order-pay.html:5 templates/payments/success.html:12
msgid "Payment" msgid "Payment"
msgstr "Paiement" msgstr "Paiement"

795
poetry.lock generated

File diff suppressed because it is too large Load Diff

@ -5,30 +5,31 @@ description = ""
authors = ["CCrypto <code@ccrypto.org>"] authors = ["CCrypto <code@ccrypto.org>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.7,<4.0" python = ">=3.8,<4.0"
django = "^3.0" django = "^4.0.0"
jsonfield = "^3.1" jsonfield = "^3.1"
django_countries = "^7" django_countries = "^7"
markdown = "^3.1" markdown = "^3.1"
requests = "^2.21" requests = "^2.21"
pygal = "^2.4" pygal = "^3.0"
pytz = "^2021.1" pytz = "^2022.1"
stripe = "^2.24" stripe = "^2.24"
django-constance = {version = "^2.7",extras = ["database"]} django-constance = {version = "^2.7",extras = ["database"]}
lcoreapi = {git = "https://git.packetimpact.net/lvpn/lcoreapi.git", tag = "v1.1.1"} lcoreapi = {git = "https://git.packetimpact.net/lvpn/lcoreapi.git", tag = "v1.1.1"}
pygments = "^2.3" pygments = "^2.3"
psycopg2-binary = "^2.8" psycopg2-binary = "^2.8"
python-frontmatter = "^1" python-frontmatter = "^1"
django-tinymce4-lite = "^1.7" django-tinymce4-widget = "^6.3"
django-admin-list-filter-dropdown = "^1.0" django-admin-list-filter-dropdown = "^1.0"
django-lcore = {git = "https://git.packetimpact.net/lvpn/django-lcore.git"} django-lcore = {git = "https://git.packetimpact.net/lvpn/django-lcore.git"}
django-pipayments = {git = "git@git.packetimpact.net:lvpn/django-pipayments.git", branch = "main"} django-pipayments = {git = "git@git.packetimpact.net:lvpn/django-pipayments.git", branch = "main"}
#django-pipayments = {path = "../lvpn/django-pipayments", develop=true} #django-pipayments = {path = "../lvpn/django-pipayments", develop=true}
celery = "^5" celery = "^5"
django-celery-beat = "^2.0.0" django-celery-beat = {git="https://github.com/celery/django-celery-beat",rev="10123d357567ae31f241f89d98561220887799ae"}
redis = "^3.5.3" redis = "^4.3"
flower = "^1" flower = "^1"
django-extensions = "^3.1.3" django-extensions = "^3.1.3"
tzdata = "^2022.1"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pylint = "^2.3" pylint = "^2.3"

@ -731,6 +731,15 @@ ul.errorlist {
margin: auto; margin: auto;
} }
p.home-whyus {
width: 47%;
margin: auto;
border: 2px solid #1c619a;
padding: 0.5em 1em;
background: #f8F8FF;
}
@media screen and (max-width: 80em) { @media screen and (max-width: 80em) {
.homepage .features { .homepage .features {
margin-left: 0; margin-left: 0;
@ -764,11 +773,20 @@ a.home-signup-button {
font-size: 1.1em; font-size: 1.1em;
font-weight: 600; font-weight: 600;
} }
a.home-signup-button .subtext {
font-size: 0.7em;
font-weight: normal;
display: block;
opacity: 0.85;
}
@media screen and (max-width: 48em) { @media screen and (max-width: 48em) {
.home-signup-button { .home-signup-button {
min-width: 50%; min-width: 50%;
} }
p.home-whyus {
width: 90%;
}
} }
@ -1236,6 +1254,9 @@ div.ticket-message-private {
.homepage h2 { .homepage h2 {
text-shadow: 0px 0px 5px #ffd99f50; text-shadow: 0px 0px 5px #ffd99f50;
} }
p.home-whyus {
background: #22222b;
}
.content-box { .content-box {
background: #272727; background: #272727;

@ -63,9 +63,19 @@
<p class="home-signup"> <p class="home-signup">
<a href="/account/signup" class="home-signup-button button inverted"> <a href="/account/signup" class="home-signup-button button inverted">
{% trans 'Sign up & try for a week for free' %} {% trans 'Sign up & try for a week for free' %}
<span class="subtext">{% trans "No CC required, 3€/month after 7 days" %}</span>
</a> </a>
</p> </p>
<p class="home-whyus">
<b>{% trans "CCrypto is a non-profit organization." %}</b><br />
{% blocktrans trimmed %}
As such, we pledge that we will never sell your personal information, exploit your trust or data,
or get acquired by a company without such boundaries.
Your payments will go exclusively towards funding our services and staff, or to other non-profits.
{% endblocktrans %}
</p>
<div class="locations"> <div class="locations">
<object id="map" data="{% static 'img/world.svg' %}" type="image/svg+xml"></object> <object id="map" data="{% static 'img/world.svg' %}" type="image/svg+xml"></object>
{{gateway_locations|json_script:"locations-data"}} {{gateway_locations|json_script:"locations-data"}}

@ -33,23 +33,26 @@
<tr> <tr>
<td>{% trans "Subscription" %}</td> <td>{% trans "Subscription" %}</td>
<td> <td>
{% if subscription.status == 'active' and request.user.vpnuser.subscr_is_failing %} {% if active_subscription %}
{% blocktrans trimmed with since=subscription.next_renew|default:user.vpnuser.expiration|date:'Y-m-d' backend=subscription.backend.backend_verbose_name %} {% blocktrans trimmed with until=active_subscription.next_renew|default:user.vpnuser.expiration|date:'Y-m-d' backend=active_subscription.backend.backend_verbose_name %}
<b>FAILING</b> since {{since}}. ({{backend}})<br />
Please cancel and subscribe again if you need to switch to another payment method.
{% endblocktrans %}
(<a href="{% url 'payments:cancel_subscr' %}">{% trans "cancel" %}</a>)
{% elif subscription.status == 'active' %}
{% blocktrans trimmed with until=subscription.next_renew|default:user.vpnuser.expiration|date:'Y-m-d' backend=subscription.backend.backend_verbose_name %}
<b>ACTIVE</b>. Renews on {{until}} via {{backend}}. <b>ACTIVE</b>. Renews on {{until}} via {{backend}}.
{% endblocktrans %} {% endblocktrans %}
(<a href="{% url 'payments:cancel_subscr' %}">{% trans "cancel" %}</a>) (<a href="{% url 'payments:cancel_subscr' %}">{% trans "cancel" %}</a>)
{% elif last_subscription %}
{% if last_subscription.status == 'cancelled' %}
{% trans "<b>CANCELLED</b>. You can subscribe again below." %}
{% elif last_subscription.status == 'error' %}
{% trans "<b>Last payment failed</b>, likely because your card expired." %}
{% trans "You can update your subscription below." %}
{% elif last_subscription.status == 'new' %}
{% trans "Pending" %}
{% endif %}
{% else %} {% else %}
- -
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% if not subscription or subscription.status != 'active' %} {% if not active_subscription %}
<tr> <tr>
<td>{% trans "Expiration" %}</td> <td>{% trans "Expiration" %}</td>
<td> <td>
@ -66,7 +69,7 @@
</div> </div>
{% if not subscription %} {% if not active_subscription %}
<div class="content-box account-fund"> <div class="content-box account-fund">
<div class="account-payment-box account-payment-tabs"> <div class="account-payment-box account-payment-tabs">
<div class="account-payment-tab"> <div class="account-payment-tab">

@ -24,7 +24,7 @@
</fieldset> </fieldset>
</form> </form>
{% else %} {% else %}
<p>You do not have any active subscription to cancel.</p> <p>{% trans "You do not have any active subscription to cancel." %}</p>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}

@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from django.shortcuts import resolve_url from django.shortcuts import resolve_url
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils import formats from django.utils import formats
from .models import Ticket, TicketMessage, TicketNotifyAddress from .models import Ticket, TicketMessage, TicketNotifyAddress

@ -1,6 +1,6 @@
from django import forms from django import forms
from .models import TicketMessage, CATEGORY_CHOICES from .models import TicketMessage, CATEGORY_CHOICES
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
class NewTicketForm(forms.Form): class NewTicketForm(forms.Form):

@ -1,6 +1,6 @@
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.urls import reverse from django.urls import reverse
from django.template.loader import get_template from django.template.loader import get_template
from django.core.mail import send_mail from django.core.mail import send_mail

@ -3,7 +3,7 @@ from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponseNotFound from django.http.response import HttpResponseNotFound
from django.utils import timezone from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
from ccvpn.common import get_client_ip from ccvpn.common import get_client_ip
from .models import Ticket, TicketMessage from .models import Ticket, TicketMessage

Loading…
Cancel
Save