Compare commits

...

8 Commits
7.4 ... 1.7.1

Author SHA1 Message Date
Greg Price
2e4ae9c5dc Release Zulip Server 1.7.1. 2017-11-22 16:19:48 -08:00
Greg Price
139fb8c2ee changelog: Document 1.7.1 release. 2017-11-22 14:56:26 -08:00
Greg Price
93ffaa73bd i18n: Update translations (including complete Korean!) 2017-11-22 14:42:55 -08:00
Vishnu Ks
960d736e55 registration: Require an explicit realm on PreregistrationUser.
This completes the last commit's work to fix CVE-2017-0910, applying
to any invite links already created before the fix was deployed.  With
this change, all new-user registrations must match an explicit realm
in the PreregistrationUser row, except when creating a new realm.

[greg: rewrote commit message]
2017-11-22 14:42:48 -08:00
Vishnu Ks
28a3dcf787 registration: Check realm against PreregistrationUser realm.
We would allow a user with a valid invitation for one realm to use it
on a different realm instead.  On a server with multiple realms, an
authorized user of one realm could use this (by sending invites to
other email addresses they control) to create accounts on other
realms. (CVE-2017-0910)

With this commit, when sending an invitation, we record the inviting
user's realm on the PreregistrationUser row; and when registering a
user, we check that the PregistrationUser realm matches the realm the
user is trying to register on.  This resolves CVE-2017-0910 for
newly-sent invitations; the next commit completes the fix.

[greg: rewrote commit message]
2017-11-22 14:42:28 -08:00
Harshit Bansal
4eb958b6d8 purge-old-deployments: Be sure to preserve last, current, and next.
[greg: revised commit message]
2017-11-22 14:42:20 -08:00
Harshit Bansal
d35d5953c7 purge-old-deployments: Remove unnecessary path juggling.
This is a small refactor that simplifies the bugfix which follows.

[greg: revised commit message]
2017-11-22 14:42:06 -08:00
Tim Abbott
c256c5e91c install: Force a locale so our dependencies can install.
In some environments, either pip itself fails or some packages fail to
install, and setting the locale to en_US.UTF-8 resolves the issue.

We heard reports of this kind of behavior with at least two different
sets of symptoms, with 1.7.0 or its release candidates:
  https://chat.zulip.org/#narrow/stream/general/subject/Trusty.201.2E7.20Upgrade/near/302214
  https://chat.zulip.org/#narrow/stream/production.20help/subject/1.2E6.20to.201.2E7/near/306250

In all reported cases, this fixed it.  This change was included in
1.7.0-rc2 and went through testing there, but by mistake was omitted
from the 1.7.0 release.

[greg: cut LC_CTYPE; move `install` line from very top to
 an appropriate spot; rewrite comments and commit message.]
2017-11-22 14:39:59 -08:00
22 changed files with 1457 additions and 1398 deletions

View File

@@ -7,6 +7,28 @@ All notable changes to the Zulip server are documented in this file.
This section lists notable unreleased changes; it is generally updated This section lists notable unreleased changes; it is generally updated
in bursts. in bursts.
### 1.7.1 -- 2017-11-21
This is a security release, with a handful of cherry-picked changes
since 1.7.0. All Zulip server admins are encouraged to upgrade
promptly.
This release includes fixes for the upgrade process, so server admins
running a version from before 1.7 should upgrade directly to 1.7.1.
- CVE-2017-0910: On a server with multiple realms, a vulnerability in
the invitation system allowed an authorized user of one realm to
create an account on any other realm.
- The Korean translation is now complete, a huge advance from almost
nothing in 1.7.0. The French translation is now nearly complete,
and several other languages have smaller updates.
- The installer now sets LC_ALL to a known locale, working around an
issue where some dependencies fail to install in some locales.
- We fixed a bug in the script that runs after upgrading Zulip (so
the fix applies when upgrading to this version), where the
garbage-collection of old deployments sometimes wouldn't preserve
the immediate last deployment.
### 1.7.0 -- 2017-10-25 ### 1.7.0 -- 2017-10-25
**Highlights:** **Highlights:**

View File

@@ -54,7 +54,7 @@ author = u'The Zulip Team'
# The short X.Y version. # The short X.Y version.
version = '1.7' version = '1.7'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '1.7.0' release = '1.7.1'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@@ -39,6 +39,9 @@ fi
# Do set -x after option parsing is complete # Do set -x after option parsing is complete
set -x set -x
# Force a known locale. Some packages on PyPI fail to install in some locales.
export LC_ALL="en_US.UTF-8"
# Specify options for apt. # Specify options for apt.
APT_OPTIONS="${APT_OPTIONS:-}" APT_OPTIONS="${APT_OPTIONS:-}"
# Install additional packages using apt. # Install additional packages using apt.

View File

@@ -12,6 +12,9 @@ import logging
os.environ["PYTHONUNBUFFERED"] = "y" os.environ["PYTHONUNBUFFERED"] = "y"
# Force a known locale. Some packages on PyPI fail to install in some locales.
os.environ["LC_ALL"] = "en_US.UTF-8"
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
from scripts.lib.zulip_tools import DEPLOYMENTS_DIR, FAIL, WARNING, ENDC, su_to_zulip from scripts.lib.zulip_tools import DEPLOYMENTS_DIR, FAIL, WARNING, ENDC, su_to_zulip

View File

@@ -210,19 +210,23 @@ def get_recent_deployments(threshold_days):
recent = set() recent = set()
threshold_date = datetime.datetime.now() - datetime.timedelta(days=threshold_days) threshold_date = datetime.datetime.now() - datetime.timedelta(days=threshold_days)
for dir_name in os.listdir(DEPLOYMENTS_DIR): for dir_name in os.listdir(DEPLOYMENTS_DIR):
if not os.path.isdir(os.path.join(DEPLOYMENTS_DIR, dir_name)): target_dir = os.path.join(DEPLOYMENTS_DIR, dir_name)
if not os.path.isdir(target_dir):
# Skip things like uwsgi sockets, symlinks, etc. # Skip things like uwsgi sockets, symlinks, etc.
continue continue
if not os.path.exists(os.path.join(DEPLOYMENTS_DIR, dir_name, "zerver")): if not os.path.exists(os.path.join(target_dir, "zerver")):
# Skip things like "lock" that aren't actually a deployment directory # Skip things like "lock" that aren't actually a deployment directory
continue continue
try: try:
date = datetime.datetime.strptime(dir_name, TIMESTAMP_FORMAT) date = datetime.datetime.strptime(dir_name, TIMESTAMP_FORMAT)
if date >= threshold_date: if date >= threshold_date:
recent.add(os.path.join(DEPLOYMENTS_DIR, dir_name)) recent.add(target_dir)
except ValueError: except ValueError:
# Always include deployments whose name is not in the format of a timestamp. # Always include deployments whose name is not in the format of a timestamp.
recent.add(os.path.join(DEPLOYMENTS_DIR, dir_name)) recent.add(target_dir)
# If it is a symlink then include the target as well.
if os.path.islink(target_dir):
recent.add(os.path.realpath(target_dir))
if os.path.exists("/root/zulip"): if os.path.exists("/root/zulip"):
recent.add("/root/zulip") recent.add("/root/zulip")
return recent return recent

View File

@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: Zulip\n" "Project-Id-Version: Zulip\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-24 23:08+0000\n" "POT-Creation-Date: 2017-10-24 23:08+0000\n"
"PO-Revision-Date: 2017-10-24 09:52+0000\n" "PO-Revision-Date: 2017-10-29 17:54+0000\n"
"Last-Translator: Tim Abbott <tabbott@kandralabs.com>\n" "Last-Translator: Tim Abbott <tabbott@kandralabs.com>\n"
"Language-Team: Bulgarian (http://www.transifex.com/zulip/zulip/language/bg/)\n" "Language-Team: Bulgarian (http://www.transifex.com/zulip/zulip/language/bg/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@@ -3,10 +3,11 @@
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# #
# Translators: # Translators:
# Kaiiju <dorian.pigeau@gmail.com>, 2017 # Dorian Pigeau <dorian.pigeau@gmail.com>, 2017
# Dorian Pigeau <dorian.pigeau@gmail.com>, 2017
# Fabrice Lamachère <fabrice.lamachere@smiden.fr>, 2017 # Fabrice Lamachère <fabrice.lamachere@smiden.fr>, 2017
# Manuel Tondeur <manueltondeur@gmail.com>, 2017 # Manuel Tondeur <manueltondeur@gmail.com>, 2017
# Mathieu GRIMARD <mathieu.grimard@hotmail.fr>, 2017 # Mathieu Grimard <mathieu.grimard@hotmail.fr>, 2017
# Paul LUBAWY <paul.lubawy@hotmail.fr>, 2017 # Paul LUBAWY <paul.lubawy@hotmail.fr>, 2017
# psyray <psyray@free.fr>, 2017 # psyray <psyray@free.fr>, 2017
# Reid Barton <rwbarton@gmail.com>, 2015 # Reid Barton <rwbarton@gmail.com>, 2015
@@ -17,8 +18,8 @@ msgstr ""
"Project-Id-Version: Zulip\n" "Project-Id-Version: Zulip\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-24 23:08+0000\n" "POT-Creation-Date: 2017-10-24 23:08+0000\n"
"PO-Revision-Date: 2017-10-25 13:25+0000\n" "PO-Revision-Date: 2017-11-15 13:01+0000\n"
"Last-Translator: Kaiiju <dorian.pigeau@gmail.com>\n" "Last-Translator: Dorian Pigeau <dorian.pigeau@gmail.com>\n"
"Language-Team: French (http://www.transifex.com/zulip/zulip/language/fr/)\n" "Language-Team: French (http://www.transifex.com/zulip/zulip/language/fr/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@@ -494,7 +495,7 @@ msgstr "Intégrations"
#: templates/zerver/for-companies.html:23 #: templates/zerver/for-companies.html:23
msgid "The best chat for workplaces" msgid "The best chat for workplaces"
msgstr "" msgstr "Le meilleur chat pour les milieux professionnels"
#: templates/zerver/for-open-source.html:23 #: templates/zerver/for-open-source.html:23
msgid "The best chat for open source projects" msgid "The best chat for open source projects"
@@ -555,7 +556,7 @@ msgid ""
" and <a href=\"#\" class=\"empty_feed_compose_stream\">\n" " and <a href=\"#\" class=\"empty_feed_compose_stream\">\n"
" compose a new stream message</a>.</p>\n" " compose a new stream message</a>.</p>\n"
" " " "
msgstr "" msgstr "\n <p>Voyez-vous, le truc c'est... qu'il n'y a pas de messages pour vous actuellement. Je suis sûr que quelqu'un vous en enverra un.</p>\n\n <p>Ou, <strong>prenez les choses en main</strong>,\n et <a href=\"#\" class=\"empty_feed_compose_stream\">\n écrivez un nouveau message de canal</a>.</p>\n "
#: templates/zerver/home.html:26 #: templates/zerver/home.html:26
msgid "Nothing's been sent here yet!" msgid "Nothing's been sent here yet!"
@@ -605,7 +606,7 @@ msgstr "Cet utilisateur n'existe pas !"
#: templates/zerver/home.html:72 #: templates/zerver/home.html:72
msgid "" msgid ""
"You aren't subscribed to this stream and nobody has talked about that yet!" "You aren't subscribed to this stream and nobody has talked about that yet!"
msgstr "" msgstr "Vous n'êtes pas abonné à ce canal et personne n'en a encore parlé!"
#: templates/zerver/home.html:75 #: templates/zerver/home.html:75
msgid "Subscribe" msgid "Subscribe"
@@ -626,7 +627,7 @@ msgid ""
" <p>Learn more about starring messages at <a href=\"/help/star-a-message\">\n" " <p>Learn more about starring messages at <a href=\"/help/star-a-message\">\n"
" %(realm_uri)s/help/star-a-message</a>.</p>\n" " %(realm_uri)s/help/star-a-message</a>.</p>\n"
" " " "
msgstr "" msgstr "\n <p>Apprenez-en plus à propos des messages favoris dans <a href=\"/help/star-a-message\">\n %(realm_uri)s/help/star-a-message</a>.</p>\n "
#: templates/zerver/home.html:91 #: templates/zerver/home.html:91
msgid "You have no unread messages!" msgid "You have no unread messages!"
@@ -643,7 +644,7 @@ msgid ""
" <p>Learn more about mentions at <a href=\"/help/at-mention-a-team-member\">\n" " <p>Learn more about mentions at <a href=\"/help/at-mention-a-team-member\">\n"
" %(realm_uri)s/help/at-mention-a-team-member</a>.</p>\n" " %(realm_uri)s/help/at-mention-a-team-member</a>.</p>\n"
" " " "
msgstr "" msgstr "\n <p>Apprenez-en plus à propos des mentions dans <a href=\"/help/at-mention-a-team-member\">\n %(realm_uri)s/help/at-mention-a-team-member</a>.</p>\n "
#: templates/zerver/home.html:102 #: templates/zerver/home.html:102
msgid "Nobody has talked about that yet!" msgid "Nobody has talked about that yet!"
@@ -657,13 +658,13 @@ msgstr "Chargement..."
msgid "" msgid ""
"If this message does not go away, please wait a couple seconds and <a " "If this message does not go away, please wait a couple seconds and <a "
"href=\"javascript:location.reload(true)\">reload</a> the page." "href=\"javascript:location.reload(true)\">reload</a> the page."
msgstr "" msgstr "Si ce message ne s'est pas envoyé, veuillez attendre quelques secondes et <a href=\"javascript:location.reload(true)\">rechargez</a> la page"
#: templates/zerver/index.html:70 #: templates/zerver/index.html:70
msgid "" msgid ""
"<strong class=\"message\">Unable to connect to\n" "<strong class=\"message\">Unable to connect to\n"
" Zulip.</strong> Updates may be delayed." " Zulip.</strong> Updates may be delayed."
msgstr "" msgstr "<strong class=\"message\">Impossoble de se connecter à\n Zulip.</strong> Les mises à jour sont peut-être reportées."
#: templates/zerver/index.html:71 #: templates/zerver/index.html:71
msgid "Retrying soon..." msgid "Retrying soon..."
@@ -686,7 +687,7 @@ msgid ""
" and\n" " and\n"
" <a href=\"/integrations/doc/iftt\">IFTTT</a>.\n" " <a href=\"/integrations/doc/iftt\">IFTTT</a>.\n"
" " " "
msgstr "" msgstr "\n Et des centaines de plus dans\n <a href=\"/integrations/doc/hubot\">Hubot</a>,\n <a href=\"/integrations/doc/zapier\">Zapier</a>,\n et\n <a href=\"/integrations/doc/iftt\">IFTTT</a>.\n "
#: templates/zerver/integrations/index.html:46 #: templates/zerver/integrations/index.html:46
msgid "Search integrations" msgid "Search integrations"
@@ -796,7 +797,7 @@ msgstr "Premier message"
#: templates/zerver/keyboard_shortcuts.html:52 #: templates/zerver/keyboard_shortcuts.html:52
msgid "Composing messages" msgid "Composing messages"
msgstr "" msgstr "En train d'écrire un message"
#: templates/zerver/keyboard_shortcuts.html:57 #: templates/zerver/keyboard_shortcuts.html:57
msgid "Reply to message" msgid "Reply to message"
@@ -824,7 +825,7 @@ msgstr "Insérer une nouvelle ligne"
#: templates/zerver/keyboard_shortcuts.html:94 #: templates/zerver/keyboard_shortcuts.html:94
msgid "Narrowing" msgid "Narrowing"
msgstr "" msgstr "Réduction"
#: templates/zerver/keyboard_shortcuts.html:99 #: templates/zerver/keyboard_shortcuts.html:99
msgid "Narrow by stream" msgid "Narrow by stream"
@@ -864,7 +865,7 @@ msgstr "Montrer le profil de l'expéditeur du message"
#: templates/zerver/keyboard_shortcuts.html:138 #: templates/zerver/keyboard_shortcuts.html:138
msgid "Show images in thread" msgid "Show images in thread"
msgstr "" msgstr "Montrer les images dans le fil"
#: templates/zerver/keyboard_shortcuts.html:142 #: templates/zerver/keyboard_shortcuts.html:142
msgid "Edit selected message" msgid "Edit selected message"
@@ -1078,13 +1079,13 @@ msgid ""
"Zulip needs your permission to\n" "Zulip needs your permission to\n"
" <a class=\"request-desktop-notifications alert-link\">enable desktop notifications.</a>\n" " <a class=\"request-desktop-notifications alert-link\">enable desktop notifications.</a>\n"
" " " "
msgstr "" msgstr "Zulip a besoin de votre permission pour\n <a class=\"request-desktop-notifications alert-link\">activer les notifications de bureau.</a>\n "
#: templates/zerver/navbar.html:10 #: templates/zerver/navbar.html:10
msgid "" msgid ""
"We strongly recommend enabling desktop notifications. They help Zulip keep " "We strongly recommend enabling desktop notifications. They help Zulip keep "
"your team connected." "your team connected."
msgstr "" msgstr "Nous vous recommandons fortement d'activer les notifications de bureau. Elles aident Zulip à garder votre équipe connectée."
#: templates/zerver/navbar.html:12 #: templates/zerver/navbar.html:12
msgid "Enable notifications" msgid "Enable notifications"
@@ -1190,13 +1191,13 @@ msgid ""
" Contact this <a href=\"mailto:%(support_email)s\">server's administrator</a>\n" " Contact this <a href=\"mailto:%(support_email)s\">server's administrator</a>\n"
" if you have any questions.\n" " if you have any questions.\n"
" " " "
msgstr "" msgstr "\n Cette installation de Zulip n'a pas de politique de confidentialité configurée.\n Contactez cet <a href=\"mailto:%(support_email)s\">administrateur de serveur</a>\n si vous avez des questions.\n "
#: templates/zerver/realm_creation_failed.html:8 #: templates/zerver/realm_creation_failed.html:8
msgid "" msgid ""
"This server does not allow members of the public to create new " "This server does not allow members of the public to create new "
"organizations." "organizations."
msgstr "" msgstr "Ce serveur ne permet pas aux membres publics de créer de nouvelles organisations."
#: templates/zerver/realm_creation_failed.html:9 #: templates/zerver/realm_creation_failed.html:9
msgid "" msgid ""
@@ -1210,7 +1211,7 @@ msgid ""
" <h1>You're almost there.</h1>\n" " <h1>You're almost there.</h1>\n"
" <p>We just need you to do one last thing.</p>\n" " <p>We just need you to do one last thing.</p>\n"
" " " "
msgstr "" msgstr "\n <h1>Vous y êtes presque.</h1>\n <p>Nous avons besoin de vous pour une dernière étape.</p>\n "
#: templates/zerver/register.html:43 #: templates/zerver/register.html:43
msgid "Full name or 名前" msgid "Full name or 名前"
@@ -1224,7 +1225,7 @@ msgstr "Nom complet"
msgid "" msgid ""
"This is used for mobile applications and other tools that require a " "This is used for mobile applications and other tools that require a "
"password." "password."
msgstr "" msgstr "Ceci est utilisé pour les applications mobiles et autres outils qui requièrent un mot de passe."
#: templates/zerver/register.html:71 #: templates/zerver/register.html:71
msgid "Password strength" msgid "Password strength"
@@ -1249,7 +1250,7 @@ msgstr "Utilise %(external_host)s"
#: templates/zerver/register.html:132 #: templates/zerver/register.html:132
msgid "The address you'll use to sign in to your organization." msgid "The address you'll use to sign in to your organization."
msgstr "" msgstr "L'adresse que vous allez utiliser pour vous inscrire à votre organisation."
#: templates/zerver/register.html:153 #: templates/zerver/register.html:153
#, python-format #, python-format
@@ -1353,7 +1354,7 @@ msgstr "Centrer l'affichage autour de l'ID du message"
#: templates/zerver/search_operators.html:41 #: templates/zerver/search_operators.html:41
msgid "Narrow to just message ID" msgid "Narrow to just message ID"
msgstr "" msgstr "Restreindre à l'ID de message"
#: templates/zerver/search_operators.html:46 #: templates/zerver/search_operators.html:46
msgid "Narrow to messages with alert words." msgid "Narrow to messages with alert words."
@@ -1420,7 +1421,7 @@ msgid ""
" <span class=\"operator_value\">keyword</span>.\n" " <span class=\"operator_value\">keyword</span>.\n"
" </p>\n" " </p>\n"
" " " "
msgstr "" msgstr "\n <p>Vous pouvez utiliser dans une seule queue n'importe quelle combinaison parmi ces opérateurs de recherche. Par exemple:</p>\n\n <p>\n &nbsp;\n <span class=\"operator\">\n Canal:<span class=\"operator_value\">nomdecanal</span>\n envoyeur:<span class=\"operator_value\">user@example.com</span>\n <span class=\"operator_value\">mot clé</span>\n </span>\n </p>\n\n <p>\n va chercher pour les messages envoyés par\n <span class=\"operator_value\">user@example.com</span>\n au canal\n <span class=\"operator_value\">nomdecanal</span>\n contenant le mot clé\n <span class=\"operator_value\">mot clé</span>.\n </p>\n "
#: templates/zerver/settings_overlay.html:16 #: templates/zerver/settings_overlay.html:16
msgid "Your account" msgid "Your account"
@@ -1526,11 +1527,11 @@ msgid ""
" Contact this <a href=\"mailto:%(support_email)s\">server's administrator</a>\n" " Contact this <a href=\"mailto:%(support_email)s\">server's administrator</a>\n"
" if you have any questions.\n" " if you have any questions.\n"
" " " "
msgstr "" msgstr "\n Cette installation de Zulip n'a pas de conditions d'utilisations configurées.\n Contactez cet <a href=\"mailto:%(support_email)s\">administrateur de serveur</a>\n si vous avez des questions.\n "
#: templates/zerver/unsubscribe_link_error.html:5 #: templates/zerver/unsubscribe_link_error.html:5
msgid "Unknown email unsubscribe request" msgid "Unknown email unsubscribe request"
msgstr "" msgstr "Requête de désabonnement d'email inconnu"
#: templates/zerver/unsubscribe_link_error.html:7 #: templates/zerver/unsubscribe_link_error.html:7
msgid "" msgid ""
@@ -1546,7 +1547,7 @@ msgid ""
"%%20e-" "%%20e-"
"mail%%2C%%20but%%20it%%20took%%20me%%20to%%20an%%20error%%20page%%3A%%0A%%0A_____________%%0A%%0APlease%%20unsubscribe%%20me.%%0A%%0AThanks%%2C%%0A_____________%%0A\">email" "mail%%2C%%20but%%20it%%20took%%20me%%20to%%20an%%20error%%20page%%3A%%0A%%0A_____________%%0A%%0APlease%%20unsubscribe%%20me.%%0A%%0AThanks%%2C%%0A_____________%%0A\">email"
" us</a> and we'll get this squared away!" " us</a> and we'll get this squared away!"
msgstr "" msgstr "Veuillez vérifier deux fois que vous avez l'URL complète et réessayez, ou <a href=\"mailto:%(support_email)s?Subject=Unsubscribe%%20me%%2C%%20please!&Body=Hi%%20there!%%0A%%0AI%%20clicked%%20this%%20unsubscribe%%20link%%20in%%20a%%20Zulip%%20e-mail%%2C%%20but%%20it%%20took%%20me%%20to%%20an%%20error%%20page%%3A%%0A%%0A_____________%%0A%%0APlease%%20unsubscribe%%20me.%%0A%%0AThanks%%2C%%0A_____________%%0A\">envoyez-nous un email</a> et nous remettrons tout en place!"
#: templates/zerver/unsubscribe_success.html:5 #: templates/zerver/unsubscribe_success.html:5
msgid "Email settings updated" msgid "Email settings updated"
@@ -1557,7 +1558,7 @@ msgstr "Paramètres du courriel mis à jour"
msgid "" msgid ""
"We've updated your email subscription settings, and you won't get " "We've updated your email subscription settings, and you won't get "
"%(subscription_type)s emails anymore." "%(subscription_type)s emails anymore."
msgstr "" msgstr "Nous avons mis à jour vos paramètres d'inscription email, et vous n'aurez plus d'emails %(subscription_type)s."
#: templates/zerver/unsubscribe_success.html:9 #: templates/zerver/unsubscribe_success.html:9
#, python-format #, python-format
@@ -1584,7 +1585,7 @@ msgstr "\n <p>Votre organisation a été migrée de zulip.com à zulipchat.co
#: zerver/decorator.py:119 zerver/lib/emoji.py:42 zerver/views/invite.py:25 #: zerver/decorator.py:119 zerver/lib/emoji.py:42 zerver/views/invite.py:25
msgid "Must be a realm administrator" msgid "Must be a realm administrator"
msgstr "" msgstr "Doit être un administrateur du domaine"
#: zerver/decorator.py:203 #: zerver/decorator.py:203
msgid "Invalid subdomain for push notifications bouncer" msgid "Invalid subdomain for push notifications bouncer"
@@ -1592,7 +1593,7 @@ msgstr ""
#: zerver/decorator.py:212 #: zerver/decorator.py:212
msgid "This API is not available to incoming webhook bots." msgid "This API is not available to incoming webhook bots."
msgstr "" msgstr "Cette API n'est pas disponible pour les bots webhook entrants."
#: zerver/decorator.py:223 #: zerver/decorator.py:223
msgid "Account not active" msgid "Account not active"
@@ -1600,7 +1601,7 @@ msgstr "Compte non actif"
#: zerver/decorator.py:226 #: zerver/decorator.py:226
msgid "Realm for account has been deactivated" msgid "Realm for account has been deactivated"
msgstr "" msgstr "Le domaine pour le compte a été désactivé"
#: zerver/decorator.py:240 #: zerver/decorator.py:240
msgid "Account is not associated with this subdomain" msgid "Account is not associated with this subdomain"
@@ -1612,15 +1613,15 @@ msgstr "Clé API invalide"
#: zerver/decorator.py:392 #: zerver/decorator.py:392
msgid "This endpoint does not accept bot requests." msgid "This endpoint does not accept bot requests."
msgstr "" msgstr "Ce paramètre n'accepte pas les requêtes de bot."
#: zerver/decorator.py:468 #: zerver/decorator.py:468
msgid "This endpoint requires HTTP basic authentication." msgid "This endpoint requires HTTP basic authentication."
msgstr "" msgstr "Ce paramètre requière une authentification HTTP basique."
#: zerver/decorator.py:471 #: zerver/decorator.py:471
msgid "Invalid authorization header for basic auth" msgid "Invalid authorization header for basic auth"
msgstr "" msgstr "En-tête d'autorisation invalide pour l'authentification basique"
#: zerver/decorator.py:521 #: zerver/decorator.py:521
msgid "Not logged in" msgid "Not logged in"
@@ -1628,7 +1629,7 @@ msgstr "Pas connecté"
#: zerver/decorator.py:526 #: zerver/decorator.py:526
msgid "Webhook bots can only access webhooks" msgid "Webhook bots can only access webhooks"
msgstr "" msgstr "Les bots webhook n'ont accès qu'aux webhooks"
#: zerver/decorator.py:591 #: zerver/decorator.py:591
msgid "Access denied" msgid "Access denied"
@@ -1636,7 +1637,7 @@ msgstr "Accès refusé"
#: zerver/forms.py:62 #: zerver/forms.py:62
msgid "Subdomain needs to have length 3 or greater." msgid "Subdomain needs to have length 3 or greater."
msgstr "" msgstr "Le sous-domaine a besoin d'une taille de 3 ou plus."
#: zerver/forms.py:63 #: zerver/forms.py:63
msgid "Subdomain cannot start or end with a '-'." msgid "Subdomain cannot start or end with a '-'."
@@ -1666,7 +1667,7 @@ msgstr "Veuillez demander une invitation pour {email} de la part de l'administra
msgid "" msgid ""
"Your email address, {email}, is not in one of the domains that are allowed " "Your email address, {email}, is not in one of the domains that are allowed "
"to register for accounts in this organization." "to register for accounts in this organization."
msgstr "" msgstr "Votre adresse email, {email}, n'est pas dans un des domaines autorisés à s'inscrire pour les comptes de cette organisation."
#: zerver/forms.py:172 #: zerver/forms.py:172
msgid "Please use your real email address." msgid "Please use your real email address."
@@ -1690,7 +1691,7 @@ msgstr "Paramètre manquant : 'à' (destinataire)"
#: zerver/lib/actions.py:1342 #: zerver/lib/actions.py:1342
msgid "Invalid 'op' value (should be start or stop)" msgid "Invalid 'op' value (should be start or stop)"
msgstr "" msgstr "Valeur 'op' invalide (doit être start ou stop)"
#: zerver/lib/actions.py:1356 #: zerver/lib/actions.py:1356
#, python-format #, python-format
@@ -1759,7 +1760,7 @@ msgstr "Le canal '%(stream_name)s' n'existe pas"
#: zerver/lib/actions.py:1692 #: zerver/lib/actions.py:1692
#, python-format #, python-format
msgid "Not authorized to send to stream '%s'" msgid "Not authorized to send to stream '%s'"
msgstr "" msgstr "Non autorisé à envoyer sur le canal '%s'"
#: zerver/lib/actions.py:1698 #: zerver/lib/actions.py:1698
msgid "Message must have recipients" msgid "Message must have recipients"
@@ -1772,11 +1773,11 @@ msgstr "Type de message invalide"
#: zerver/lib/actions.py:1878 #: zerver/lib/actions.py:1878
msgid "You cannot get subscribers for public streams in this realm" msgid "You cannot get subscribers for public streams in this realm"
msgstr "" msgstr "Vous ne pouvez pas avoir d'abonnés sur les canaux publics dans ce domaine."
#: zerver/lib/actions.py:1881 #: zerver/lib/actions.py:1881
msgid "Unable to retrieve subscribers for invite-only stream" msgid "Unable to retrieve subscribers for invite-only stream"
msgstr "" msgstr "Impossible de retrouver les abonnés pour le canal sur invitation uniquement."
#: zerver/lib/actions.py:2493 zerver/views/users.py:72 #: zerver/lib/actions.py:2493 zerver/views/users.py:72
#: zerver/views/users.py:85 zerver/views/users.py:101 #: zerver/views/users.py:85 zerver/views/users.py:101
@@ -1814,7 +1815,7 @@ msgstr "Nous n'avons pas été capable d'inviter quelquun."
msgid "" msgid ""
"Some of those addresses are already using Zulip, so we didn't send them an " "Some of those addresses are already using Zulip, so we didn't send them an "
"invitation. We did send invitations to everyone else!" "invitation. We did send invitations to everyone else!"
msgstr "" msgstr "Certaines de ces adresses utilisent déjà Zulip, nous ne leurs avons donc pas envoyé d'invitation. Nous avons bien sûr envoyé des invitations à toutes les autres personnes!"
#: zerver/lib/addressee.py:21 #: zerver/lib/addressee.py:21
#, python-format #, python-format
@@ -1852,15 +1853,15 @@ msgstr "Le domaine ne peut pas démarrer ou se terminer avec un point (.)"
#: zerver/lib/domains.py:17 #: zerver/lib/domains.py:17
msgid "Consecutive '.' are not allowed." msgid "Consecutive '.' are not allowed."
msgstr "" msgstr "Les '.' consécutifs ne sont pas permis."
#: zerver/lib/domains.py:19 #: zerver/lib/domains.py:19
msgid "Subdomains cannot start or end with a '-'." msgid "Subdomains cannot start or end with a '-'."
msgstr "" msgstr "Les sous-domaines ne peuvent pas démarrer ou se terminer avec un '-'."
#: zerver/lib/domains.py:21 #: zerver/lib/domains.py:21
msgid "Domain can only have letters, numbers, '.' and '-'s." msgid "Domain can only have letters, numbers, '.' and '-'s."
msgstr "" msgstr "Le domaine ne peut contenir que des lettres, des nombres, des '.' et des '-'."
#: zerver/lib/emoji.py:27 #: zerver/lib/emoji.py:27
#, python-format #, python-format
@@ -1869,7 +1870,7 @@ msgstr "L'emoji '%s' n'existe pas"
#: zerver/lib/emoji.py:54 #: zerver/lib/emoji.py:54
msgid "Must be a realm administrator or emoji author" msgid "Must be a realm administrator or emoji author"
msgstr "" msgstr "Doit être une administrateur de domaine ou un auteur d'emoji"
#: zerver/lib/emoji.py:60 zerver/models.py:379 #: zerver/lib/emoji.py:60 zerver/models.py:379
msgid "Invalid characters in emoji name" msgid "Invalid characters in emoji name"
@@ -1893,7 +1894,7 @@ msgstr "Intégration continue"
#: zerver/lib/integrations.py:39 #: zerver/lib/integrations.py:39
msgid "Customer support" msgid "Customer support"
msgstr "" msgstr "Support client"
#: zerver/lib/integrations.py:40 #: zerver/lib/integrations.py:40
msgid "Deployment" msgid "Deployment"
@@ -2000,15 +2001,15 @@ msgstr "L'utilisateur ne peut pas créer de canaux."
#: zerver/lib/streams.py:210 #: zerver/lib/streams.py:210
#, python-format #, python-format
msgid "Stream(s) (%s) do not exist" msgid "Stream(s) (%s) do not exist"
msgstr "" msgstr "Le(s) canal(aux) (%s) n'existe(nt) pas"
#: zerver/lib/upload.py:111 #: zerver/lib/upload.py:111
msgid "Animated emoji must be have same width and height." msgid "Animated emoji must be have same width and height."
msgstr "" msgstr "L'emoji animé doit avoir la même largeur et hauteur."
#: zerver/lib/upload.py:114 #: zerver/lib/upload.py:114
msgid "Animated emoji can't be larger than 64px in width or height." msgid "Animated emoji can't be larger than 64px in width or height."
msgstr "" msgstr "L'emoji animé ne peut être plus large que 64px en largeur et hauteur"
#: zerver/lib/users.py:13 #: zerver/lib/users.py:13
msgid "Name too long!" msgid "Name too long!"
@@ -2028,11 +2029,11 @@ msgstr "Mauvais nom ou nom d'utilisateur"
#: zerver/lib/users.py:40 #: zerver/lib/users.py:40
msgid "Invalid bot type" msgid "Invalid bot type"
msgstr "" msgstr "Type de bot invalide"
#: zerver/lib/users.py:45 #: zerver/lib/users.py:45
msgid "Invalid interface type" msgid "Invalid interface type"
msgstr "" msgstr "Type d'interface invalide"
#: zerver/lib/validator.py:40 #: zerver/lib/validator.py:40
#, python-format #, python-format
@@ -2052,7 +2053,7 @@ msgstr "%s n'est pas un entier"
#: zerver/lib/validator.py:60 #: zerver/lib/validator.py:60
#, python-format #, python-format
msgid "%s is not a float" msgid "%s is not a float"
msgstr "" msgstr "%s n'est pas un flottant"
#: zerver/lib/validator.py:66 #: zerver/lib/validator.py:66
#, python-format #, python-format
@@ -2067,7 +2068,7 @@ msgstr "%s n'est pas une liste"
#: zerver/lib/validator.py:87 #: zerver/lib/validator.py:87
#, python-format #, python-format
msgid "%(container)s should have exactly %(length)s items" msgid "%(container)s should have exactly %(length)s items"
msgstr "" msgstr "%(container)s doit avoir exactement %(length)s éléments"
#: zerver/lib/validator.py:105 #: zerver/lib/validator.py:105
#, python-format #, python-format
@@ -2077,12 +2078,12 @@ msgstr ""
#: zerver/lib/validator.py:109 #: zerver/lib/validator.py:109
#, python-format #, python-format
msgid "%(key_name)s key is missing from %(var_name)s" msgid "%(key_name)s key is missing from %(var_name)s"
msgstr "" msgstr "La clé %(key_name)s est manquante dans %(var_name)s"
#: zerver/lib/validator.py:119 #: zerver/lib/validator.py:119
#, python-format #, python-format
msgid "Unexpected arguments: %s" msgid "Unexpected arguments: %s"
msgstr "" msgstr "Arguments inattendus: %s"
#: zerver/lib/validator.py:143 #: zerver/lib/validator.py:143
#, python-format #, python-format
@@ -2092,7 +2093,7 @@ msgstr ""
#: zerver/lib/validator.py:151 #: zerver/lib/validator.py:151
#, python-format #, python-format
msgid "%(variable)s != %(expected_value)s (%(value)s is wrong)" msgid "%(variable)s != %(expected_value)s (%(value)s is wrong)"
msgstr "" msgstr "%(variable)s != %(expected_value)s (%(value)s est faux)"
#: zerver/middleware.py:292 #: zerver/middleware.py:292
msgid "Internal server error" msgid "Internal server error"
@@ -2105,23 +2106,23 @@ msgstr "Erreur CSRF: {reason}"
#: zerver/middleware.py:349 #: zerver/middleware.py:349
msgid "API usage exceeded rate limit" msgid "API usage exceeded rate limit"
msgstr "" msgstr "L'utilisation de l'API a dépassé la limite"
#: zerver/models.py:646 #: zerver/models.py:646
msgid "Apple style" msgid "Apple style"
msgstr "" msgstr "Style Apple"
#: zerver/models.py:647 #: zerver/models.py:647
msgid "Emoji One style" msgid "Emoji One style"
msgstr "" msgstr "Style de l'emoji Une"
#: zerver/models.py:648 #: zerver/models.py:648
msgid "Google style" msgid "Google style"
msgstr "" msgstr "Style Google"
#: zerver/models.py:649 #: zerver/models.py:649
msgid "Twitter style" msgid "Twitter style"
msgstr "" msgstr "Style Twitter"
#: zerver/models.py:1208 #: zerver/models.py:1208
msgid "Unicode emoji" msgid "Unicode emoji"
@@ -2129,7 +2130,7 @@ msgstr ""
#: zerver/models.py:1209 #: zerver/models.py:1209
msgid "Realm emoji" msgid "Realm emoji"
msgstr "" msgstr "Emoji de domaine"
#: zerver/models.py:1210 #: zerver/models.py:1210
msgid "Zulip extra emoji" msgid "Zulip extra emoji"
@@ -2137,15 +2138,15 @@ msgstr ""
#: zerver/tornado/event_queue.py:520 zerver/tornado/socket.py:141 #: zerver/tornado/event_queue.py:520 zerver/tornado/socket.py:141
msgid "Missing 'queue_id' argument" msgid "Missing 'queue_id' argument"
msgstr "" msgstr "Argument 'queue_id' manquant"
#: zerver/tornado/event_queue.py:523 #: zerver/tornado/event_queue.py:523
msgid "Missing 'last_event_id' argument" msgid "Missing 'last_event_id' argument"
msgstr "" msgstr "Argument 'last_event_id' manquant"
#: zerver/tornado/event_queue.py:528 #: zerver/tornado/event_queue.py:528
msgid "You are not authorized to get events from this queue" msgid "You are not authorized to get events from this queue"
msgstr "" msgstr "Vous n'êtes pas autorisé à avoir les évènements de cette queue"
#: zerver/tornado/exceptions.py:18 #: zerver/tornado/exceptions.py:18
#, python-brace-format #, python-brace-format
@@ -2167,19 +2168,19 @@ msgstr ""
#: zerver/tornado/socket.py:149 #: zerver/tornado/socket.py:149
#, python-format #, python-format
msgid "You are not the owner of the queue with id '%s'" msgid "You are not the owner of the queue with id '%s'"
msgstr "" msgstr "Vous n'êtes pas le propriétaire de la queue avec l'id '%s'"
#: zerver/tornado/views.py:35 #: zerver/tornado/views.py:35
msgid "You are not authorized to access this queue" msgid "You are not authorized to access this queue"
msgstr "" msgstr "Vous n'avez pas l'autorisation d'accéder à cette queue"
#: zerver/views/auth.py:175 #: zerver/views/auth.py:175
msgid "No REMOTE_USER set." msgid "No REMOTE_USER set."
msgstr "" msgstr "Pas de REMOTE_USER configuré."
#: zerver/views/auth.py:193 #: zerver/views/auth.py:193
msgid "Auth key for this subdomain not found." msgid "Auth key for this subdomain not found."
msgstr "" msgstr "Clé d'authentification pour ce sous-domaine introuvable."
#: zerver/views/auth.py:200 #: zerver/views/auth.py:200
msgid "No JSON web token passed in request" msgid "No JSON web token passed in request"
@@ -2243,7 +2244,7 @@ msgstr "Sous-domaine requis"
#: zerver/views/auth.py:728 #: zerver/views/auth.py:728
msgid "GOOGLE_CLIENT_ID is not configured" msgid "GOOGLE_CLIENT_ID is not configured"
msgstr "" msgstr "Le GOOGLE_CLIENT_ID n'est pas configuré"
#: zerver/views/custom_profile_fields.py:33 #: zerver/views/custom_profile_fields.py:33
#: zerver/views/custom_profile_fields.py:66 #: zerver/views/custom_profile_fields.py:66
@@ -2252,19 +2253,19 @@ msgstr "Le nom ne peut pas être vide."
#: zerver/views/custom_profile_fields.py:36 #: zerver/views/custom_profile_fields.py:36
msgid "Invalid field type." msgid "Invalid field type."
msgstr "" msgstr "Type de champ invalide."
#: zerver/views/custom_profile_fields.py:46 #: zerver/views/custom_profile_fields.py:46
#: zerver/views/custom_profile_fields.py:77 #: zerver/views/custom_profile_fields.py:77
msgid "A field with that name already exists." msgid "A field with that name already exists."
msgstr "" msgstr "Un champ avec ce nom existe déjà."
#: zerver/views/custom_profile_fields.py:54 #: zerver/views/custom_profile_fields.py:54
#: zerver/views/custom_profile_fields.py:72 #: zerver/views/custom_profile_fields.py:72
#: zerver/views/custom_profile_fields.py:92 #: zerver/views/custom_profile_fields.py:92
#, python-brace-format #, python-brace-format
msgid "Field id {id} not found." msgid "Field id {id} not found."
msgstr "" msgstr "Champ id {id} introuvable. "
#: zerver/views/hotspots.py:16 #: zerver/views/hotspots.py:16
#, python-format #, python-format
@@ -2273,16 +2274,16 @@ msgstr "Hotspot inconnu : %s"
#: zerver/views/invite.py:27 #: zerver/views/invite.py:27
msgid "You must specify at least one email address." msgid "You must specify at least one email address."
msgstr "" msgstr "Vous devez spécifier au moins une adresse mail."
#: zerver/views/invite.py:35 #: zerver/views/invite.py:35
msgid "You must specify at least one stream for invitees to join." msgid "You must specify at least one stream for invitees to join."
msgstr "" msgstr "Vous devez spécifier au moins un canal à joindre pour les invités."
#: zerver/views/invite.py:48 #: zerver/views/invite.py:48
#, python-format #, python-format
msgid "Stream does not exist: %s. No invites were sent." msgid "Stream does not exist: %s. No invites were sent."
msgstr "" msgstr "Le canal n'existe pas: %s. Aucune invitation n'a été envoyé."
#: zerver/views/messages.py:71 #: zerver/views/messages.py:71
#, python-brace-format #, python-brace-format
@@ -2292,16 +2293,16 @@ msgstr ""
#: zerver/views/messages.py:825 #: zerver/views/messages.py:825
#, python-format #, python-format
msgid "No such topic '%s'" msgid "No such topic '%s'"
msgstr "" msgstr "Pas de topic '%s'"
#: zerver/views/messages.py:950 #: zerver/views/messages.py:950
#, python-format #, python-format
msgid "Unknown realm %s" msgid "Unknown realm %s"
msgstr "" msgstr "Domaine %s inconnu."
#: zerver/views/messages.py:970 #: zerver/views/messages.py:970
msgid "Missing sender" msgid "Missing sender"
msgstr "" msgstr "Envoyeur manquant"
#: zerver/views/messages.py:976 #: zerver/views/messages.py:976
msgid "Invalid mirrored message" msgid "Invalid mirrored message"
@@ -2313,7 +2314,7 @@ msgstr ""
#: zerver/views/messages.py:981 #: zerver/views/messages.py:981
msgid "IRC stream names must start with #" msgid "IRC stream names must start with #"
msgstr "" msgstr "Les noms de canal IRC doivent commencer par #"
#: zerver/views/messages.py:1040 #: zerver/views/messages.py:1040
msgid "Message edit history is disabled in this organization" msgid "Message edit history is disabled in this organization"
@@ -2321,19 +2322,19 @@ msgstr ""
#: zerver/views/messages.py:1058 #: zerver/views/messages.py:1058
msgid "Your organization has turned off message editing" msgid "Your organization has turned off message editing"
msgstr "" msgstr "Votre organisation a désactivé l'édition de message"
#: zerver/views/messages.py:1073 zerver/views/messages.py:1142 #: zerver/views/messages.py:1073 zerver/views/messages.py:1142
msgid "You don't have permission to edit this message" msgid "You don't have permission to edit this message"
msgstr "" msgstr "Vous n'avez pas la permission d'éditer ce message"
#: zerver/views/messages.py:1084 #: zerver/views/messages.py:1084
msgid "The time limit for editing this message has past" msgid "The time limit for editing this message has past"
msgstr "" msgstr "La limite de temps pour éditer ce message est passée"
#: zerver/views/messages.py:1087 #: zerver/views/messages.py:1087
msgid "Nothing to change" msgid "Nothing to change"
msgstr "" msgstr "Rien à changer"
#: zerver/views/muting.py:22 #: zerver/views/muting.py:22
msgid "Topic already muted" msgid "Topic already muted"
@@ -2341,7 +2342,7 @@ msgstr "Sujet déjà muet"
#: zerver/views/muting.py:29 #: zerver/views/muting.py:29
msgid "Topic is not there in the muted_topics list" msgid "Topic is not there in the muted_topics list"
msgstr "" msgstr "Le topic n'est pas ici dans la liste des muted_topics"
#: zerver/views/pointer.py:29 #: zerver/views/pointer.py:29
msgid "Invalid message ID" msgid "Invalid message ID"
@@ -2352,16 +2353,16 @@ msgstr "ID de message invalide"
#: zerver/views/users.py:98 zerver/views/users.py:168 #: zerver/views/users.py:98 zerver/views/users.py:168
#: zerver/views/users.py:226 #: zerver/views/users.py:226
msgid "No such user" msgid "No such user"
msgstr "" msgstr "Aucun utilisateur"
#: zerver/views/presence.py:34 #: zerver/views/presence.py:34
msgid "Presence is not supported for bot users." msgid "Presence is not supported for bot users."
msgstr "" msgstr "La présence n'est pas supporté pour les utilisateurs de bot."
#: zerver/views/presence.py:38 #: zerver/views/presence.py:38
#, python-format #, python-format
msgid "No presence data for %s" msgid "No presence data for %s"
msgstr "" msgstr "Pas de donné de présence pour %s"
#: zerver/views/presence.py:59 #: zerver/views/presence.py:59
#, python-format #, python-format
@@ -2501,7 +2502,7 @@ msgstr "Vous devriez télécharger seulement un fichier à la fois"
#: zerver/views/upload.py:63 #: zerver/views/upload.py:63
msgid "Upload would exceed your maximum quota." msgid "Upload would exceed your maximum quota."
msgstr "" msgstr "L'envoi devrait excéder votre quota."
#: zerver/views/user_settings.py:36 zerver/views/user_settings.py:121 #: zerver/views/user_settings.py:36 zerver/views/user_settings.py:121
msgid "Email address changes are disabled in this organization." msgid "Email address changes are disabled in this organization."

View File

@@ -256,7 +256,7 @@
"Messages older than the configured number of days will be automatically deleted": "Les messages plus anciens que le nombre de jours configuré seront automatiquement supprimés.", "Messages older than the configured number of days will be automatically deleted": "Les messages plus anciens que le nombre de jours configuré seront automatiquement supprimés.",
"Messages retention period in days (blank means messages are retained forever)": "Période de conservation des messages en jours (vide signifie que les messages sont conservés à jamais)", "Messages retention period in days (blank means messages are retained forever)": "Période de conservation des messages en jours (vide signifie que les messages sont conservés à jamais)",
"Method": "Méthode", "Method": "Méthode",
"Mobile push notifications": "", "Mobile push notifications": "Notifications mobiles",
"Mobile push notifications always (even when online)": "Toujours activer les notifications Push Mobile (même en ligne)", "Mobile push notifications always (even when online)": "Toujours activer les notifications Push Mobile (même en ligne)",
"Mobile push notifications when offline": "Notifications Push Mobile lorsque déconnecté", "Mobile push notifications when offline": "Notifications Push Mobile lorsque déconnecté",
"Most stream administration is done on the <a href=\"/#streams\">Streams page</a>.": "L'administration du canal se fait principalement sur la <a href=\"/#streams\">page des Canaux</a>.", "Most stream administration is done on the <a href=\"/#streams\">Streams page</a>.": "L'administration du canal se fait principalement sur la <a href=\"/#streams\">page des Canaux</a>.",
@@ -343,7 +343,7 @@
"Reactivate bot": "Réactiver le robot", "Reactivate bot": "Réactiver le robot",
"Receive audible notifications": "Recevoir les notifications audio", "Receive audible notifications": "Recevoir les notifications audio",
"Receive desktop notifications": "Recevoir les notifications de bureau", "Receive desktop notifications": "Recevoir les notifications de bureau",
"Receive push notifications": "", "Receive push notifications": "Recevoir les notifications",
"Regular expression": "Expression régulière", "Regular expression": "Expression régulière",
"Remove": "Supprimer", "Remove": "Supprimer",
"Remove admin": "Supprimer l'admin", "Remove admin": "Supprimer l'admin",

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Zulip\n" "Project-Id-Version: Zulip\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-25 16:18+0000\n" "POT-Creation-Date: 2017-11-21 01:20+0000\n"
"PO-Revision-Date: 2017-09-04 03:34+0000\n" "PO-Revision-Date: 2017-09-04 03:34+0000\n"
"Last-Translator: Greg Price <gnprice@gmail.com>\n" "Last-Translator: Greg Price <gnprice@gmail.com>\n"
"Language-Team: Italian (http://www.transifex.com/zulip/zulip/language/it/)\n" "Language-Team: Italian (http://www.transifex.com/zulip/zulip/language/it/)\n"
@@ -190,7 +190,8 @@ msgid "Just in case, take a look at your Spam folder."
msgstr "" msgstr ""
#: templates/zerver/bankruptcy.html:5 templates/zerver/delete_message.html:3 #: templates/zerver/bankruptcy.html:5 templates/zerver/delete_message.html:3
#: templates/zerver/invite_user.html:5 templates/zerver/lightbox_overlay.html:7 #: templates/zerver/invite_user.html:5
#: templates/zerver/lightbox_overlay.html:7
#: templates/zerver/message_history.html:4 #: templates/zerver/message_history.html:4
#: templates/zerver/message_history.html:12 templates/zerver/navbar.html:3 #: templates/zerver/message_history.html:12 templates/zerver/navbar.html:3
msgid "Close" msgid "Close"
@@ -239,7 +240,8 @@ msgstr ""
msgid "New private message" msgid "New private message"
msgstr "" msgstr ""
#: templates/zerver/compose.html:41 templates/zerver/keyboard_shortcuts.html:85 #: templates/zerver/compose.html:41
#: templates/zerver/keyboard_shortcuts.html:85
msgid "Cancel compose" msgid "Cancel compose"
msgstr "" msgstr ""
@@ -381,7 +383,8 @@ msgstr ""
msgid "Are you sure you want to delete this message?" msgid "Are you sure you want to delete this message?"
msgstr "" msgstr ""
#: templates/zerver/delete_message.html:13 templates/zerver/invite_user.html:32 #: templates/zerver/delete_message.html:13
#: templates/zerver/invite_user.html:32
#: templates/zerver/settings_sidebar.html:35 #: templates/zerver/settings_sidebar.html:35
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
@@ -1790,9 +1793,9 @@ msgstr ""
msgid "Unable to retrieve subscribers for invite-only stream" msgid "Unable to retrieve subscribers for invite-only stream"
msgstr "" msgstr ""
#: zerver/lib/actions.py:2493 zerver/views/users.py:72 zerver/views/users.py:85 #: zerver/lib/actions.py:2493 zerver/views/users.py:72
#: zerver/views/users.py:101 zerver/views/users.py:171 #: zerver/views/users.py:85 zerver/views/users.py:101
#: zerver/views/users.py:229 #: zerver/views/users.py:171 zerver/views/users.py:229
msgid "Insufficient permission" msgid "Insufficient permission"
msgstr "" msgstr ""
@@ -2360,7 +2363,8 @@ msgstr ""
#: zerver/views/presence.py:30 zerver/views/presence.py:32 #: zerver/views/presence.py:30 zerver/views/presence.py:32
#: zerver/views/users.py:39 zerver/views/users.py:41 zerver/views/users.py:82 #: zerver/views/users.py:39 zerver/views/users.py:41 zerver/views/users.py:82
#: zerver/views/users.py:98 zerver/views/users.py:168 zerver/views/users.py:226 #: zerver/views/users.py:98 zerver/views/users.py:168
#: zerver/views/users.py:226
msgid "No such user" msgid "No such user"
msgstr "" msgstr ""

View File

@@ -4,15 +4,15 @@
# #
# Translators: # Translators:
# Greg Price <gnprice@gmail.com>, 2017 # Greg Price <gnprice@gmail.com>, 2017
# Kouhei Sutou <kou@cozmixng.org>, 2016 # Kouhei Sutou <kou@cozmixng.org>, 2016-2017
# Tetsuya Morimoto <tetsuya.morimoto@gmail.com>, 2017 # Tetsuya Morimoto <tetsuya.morimoto@gmail.com>, 2017
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Zulip\n" "Project-Id-Version: Zulip\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-24 23:08+0000\n" "POT-Creation-Date: 2017-10-24 23:08+0000\n"
"PO-Revision-Date: 2017-10-24 01:09+0000\n" "PO-Revision-Date: 2017-11-03 11:15+0000\n"
"Last-Translator: Tetsuya Morimoto <tetsuya.morimoto@gmail.com>\n" "Last-Translator: Greg Price <gnprice@gmail.com>\n"
"Language-Team: Japanese (http://www.transifex.com/zulip/zulip/language/ja/)\n" "Language-Team: Japanese (http://www.transifex.com/zulip/zulip/language/ja/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@@ -41,7 +41,7 @@ msgstr "%(realm_name)s のZulip解析"
#: templates/analytics/stats.html:21 #: templates/analytics/stats.html:21
msgid "Messages sent over time" msgid "Messages sent over time"
msgstr "メッセージは時間をかけて送信されました。" msgstr "時間毎の送信メッセージ数"
#: templates/analytics/stats.html:23 #: templates/analytics/stats.html:23
msgid "Aggregation" msgid "Aggregation"
@@ -74,7 +74,7 @@ msgstr "ボット"
#: templates/analytics/stats.html:44 #: templates/analytics/stats.html:44
msgid "Messages sent by client" msgid "Messages sent by client"
msgstr "クライアントが送信したメッセージ" msgstr "クライアント毎の送信メッセージ"
#: templates/analytics/stats.html:48 templates/analytics/stats.html:66 #: templates/analytics/stats.html:48 templates/analytics/stats.html:66
msgid "Everyone" msgid "Everyone"
@@ -98,7 +98,7 @@ msgstr "全期間"
#: templates/analytics/stats.html:61 #: templates/analytics/stats.html:61
msgid "Messages sent by recipient type" msgid "Messages sent by recipient type"
msgstr "受信者の種別で送信されたメッセージ" msgstr "宛先タイプ毎の送信メッセージ"
#: templates/analytics/stats.html:76 #: templates/analytics/stats.html:76
msgid "Active users" msgid "Active users"
@@ -492,7 +492,7 @@ msgstr "ワークプレースのベストチャート"
#: templates/zerver/for-open-source.html:23 #: templates/zerver/for-open-source.html:23
msgid "The best chat for open source projects" msgid "The best chat for open source projects"
msgstr "オープンソースプロジェクトのベストチャト" msgstr "オープンソースプロジェクトのベストチャト"
#: templates/zerver/for-working-groups-and-communities.html:23 #: templates/zerver/for-working-groups-and-communities.html:23
msgid "The best chat for working groups and communities" msgid "The best chat for working groups and communities"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@ msgstr ""
"Project-Id-Version: Zulip\n" "Project-Id-Version: Zulip\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-10-24 23:08+0000\n" "POT-Creation-Date: 2017-10-24 23:08+0000\n"
"PO-Revision-Date: 2017-10-23 23:18+0000\n" "PO-Revision-Date: 2017-11-03 12:14+0000\n"
"Last-Translator: Tim Abbott <tabbott@kandralabs.com>\n" "Last-Translator: Tim Abbott <tabbott@kandralabs.com>\n"
"Language-Team: Russian (http://www.transifex.com/zulip/zulip/language/ru/)\n" "Language-Team: Russian (http://www.transifex.com/zulip/zulip/language/ru/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -103,7 +103,7 @@ msgstr ""
#: templates/analytics/stats.html:76 #: templates/analytics/stats.html:76
msgid "Active users" msgid "Active users"
msgstr "" msgstr "Активных пользователей"
#: templates/analytics/stats.html:80 templates/zerver/settings_overlay.html:69 #: templates/analytics/stats.html:80 templates/zerver/settings_overlay.html:69
msgid "Users" msgid "Users"
@@ -231,7 +231,7 @@ msgstr ""
#: templates/zerver/compose.html:98 #: templates/zerver/compose.html:98
#: templates/zerver/keyboard_shortcuts.html:173 #: templates/zerver/keyboard_shortcuts.html:173
msgid "Drafts" msgid "Drafts"
msgstr "" msgstr "Черновики"
#: templates/zerver/compose.html:17 templates/zerver/compose.html:18 #: templates/zerver/compose.html:17 templates/zerver/compose.html:18
msgid "New topic" msgid "New topic"
@@ -373,7 +373,7 @@ msgstr ""
#: templates/zerver/delete_message.html:4 #: templates/zerver/delete_message.html:4
msgid "Delete message" msgid "Delete message"
msgstr "" msgstr "Удалить сообщение"
#: templates/zerver/delete_message.html:8 #: templates/zerver/delete_message.html:8
msgid "Are you sure you want to delete this message?" msgid "Are you sure you want to delete this message?"
@@ -1120,7 +1120,7 @@ msgstr "Настройки"
#: templates/zerver/navbar.html:85 #: templates/zerver/navbar.html:85
msgid "Manage organization" msgid "Manage organization"
msgstr "" msgstr "Управление организацией"
#: templates/zerver/navbar.html:91 #: templates/zerver/navbar.html:91
msgid "User documentation" msgid "User documentation"
@@ -1435,7 +1435,7 @@ msgstr "Ваши боты"
#: templates/zerver/settings_overlay.html:32 #: templates/zerver/settings_overlay.html:32
msgid "Alert words" msgid "Alert words"
msgstr "" msgstr "Сигнальные слова"
#: templates/zerver/settings_overlay.html:36 #: templates/zerver/settings_overlay.html:36
msgid "Uploaded files" msgid "Uploaded files"
@@ -1443,7 +1443,7 @@ msgstr ""
#: templates/zerver/settings_overlay.html:40 #: templates/zerver/settings_overlay.html:40
msgid "Muted topics" msgid "Muted topics"
msgstr "" msgstr "Заглушенные темы"
#: templates/zerver/settings_overlay.html:44 #: templates/zerver/settings_overlay.html:44
msgid "Zulip labs" msgid "Zulip labs"
@@ -1451,7 +1451,7 @@ msgstr ""
#: templates/zerver/settings_overlay.html:49 #: templates/zerver/settings_overlay.html:49
msgid "Organization profile" msgid "Organization profile"
msgstr "" msgstr "Профиль организации"
#: templates/zerver/settings_overlay.html:53 #: templates/zerver/settings_overlay.html:53
msgid "Organization settings" msgid "Organization settings"
@@ -1483,7 +1483,7 @@ msgstr "Каналы по умолчанию"
#: templates/zerver/settings_overlay.html:93 #: templates/zerver/settings_overlay.html:93
msgid "Filter settings" msgid "Filter settings"
msgstr "" msgstr "Настройки фильтров"
#: templates/zerver/settings_sidebar.html:9 #: templates/zerver/settings_sidebar.html:9
msgid "Edit bot" msgid "Edit bot"

View File

@@ -1,23 +1,23 @@
{ {
"\"__file_name__\" was too large; the maximum file size is 25MiB.": "", "\"__file_name__\" was too large; the maximum file size is 25MiB.": "",
"(This user has been deactivated)": "", "(This user has been deactivated)": "(Этот пользователь был отключен)",
"(no topic)": "(без темы)", "(no topic)": "(без темы)",
"24-hour time (17:00 instead of 5:00 PM)": "", "24-hour time (17:00 instead of 5:00 PM)": "Время в 24-часовом формате (17:00 вместо 5:00 PM)",
"<b>Private:</b> must be invited by a member; new members can only see messages sent after they join; hidden from non-administrator users": "", "<b>Private:</b> must be invited by a member; new members can only see messages sent after they join; hidden from non-administrator users": "",
"<b>Public:</b> anyone can join; anyone can view complete message history without joining": "", "<b>Public:</b> anyone can join; anyone can view complete message history without joining": "",
"<p>Lets everyone know about the new stream,<br /> even if you don't add them.</p>": "", "<p>Lets everyone know about the new stream,<br /> even if you don't add them.</p>": "",
"<strong>__name__</strong> is not subscribed to this stream.": "Пользователь <strong>__name__</strong> не подписан на канал.", "<strong>__name__</strong> is not subscribed to this stream.": "Пользователь <strong>__name__</strong> не подписан на канал.",
"A stream needs to have a name": "Укажите название канала", "A stream needs to have a name": "Укажите название канала",
"A stream with this name already exists": "Канал с таким именем уже существует", "A stream with this name already exists": "Канал с таким именем уже существует",
"API key": "", "API key": "API ключ",
"Action": "Действие", "Action": "Действие",
"Actions": "Действия", "Actions": "Действия",
"Active bots": "", "Active bots": "Активные боты",
"Active now": "", "Active now": "Активно сейчас",
"Active users": "", "Active users": "Активных пользователей",
"Add": "Добавить", "Add": "Добавить",
"Add a new alert word": "Добавить новое сигнальное слово", "Add a new alert word": "Добавить новое сигнальное слово",
"Add a new bot": "", "Add a new bot": "Добавить нового бота",
"Add a new emoji": "Добавить эмодзи", "Add a new emoji": "Добавить эмодзи",
"Add a new filter": "Добавить новый фильтр", "Add a new filter": "Добавить новый фильтр",
"Add alert word": "Добавить сигнальное слово", "Add alert word": "Добавить сигнальное слово",
@@ -27,22 +27,22 @@
"Add extra emoji for members of the __realm_name__ organization.": "Добавить дополнительные эмодзи для участников организации __realm_name__.", "Add extra emoji for members of the __realm_name__ organization.": "Добавить дополнительные эмодзи для участников организации __realm_name__.",
"Add filter": "Добавить фильтр", "Add filter": "Добавить фильтр",
"Add new default stream": "Добавить новый канал по умолчанию", "Add new default stream": "Добавить новый канал по умолчанию",
"Add stream": "", "Add stream": "Добавить канал",
"Added successfully!": "", "Added successfully!": "Добавлено успешно!",
"Alert word": "", "Alert word": "Сигнальное слово",
"Alert word added successfully!": "", "Alert word added successfully!": "Сигнальное слово успешно добавлено!",
"Alert word already exists!": "", "Alert word already exists!": "Сигнальное слово уже существует!",
"Alert word can't be empty!": "", "Alert word can't be empty!": "Сигнальное слово не может быть пустым!",
"Alert word removed successfully!": "", "Alert word removed successfully!": "Сигнальное слово успешно удалено!",
"Alert words": "", "Alert words": "Сигнальные слова",
"Alert words allow you to be notified as if you were @-mentioned when certain words or phrases are used in Zulip.": "Сигнальные слова позволяют вам получать уведомления, когда кто-то использует эти слова или фразы в Zulip", "Alert words allow you to be notified as if you were @-mentioned when certain words or phrases are used in Zulip.": "Сигнальные слова позволяют вам получать уведомления, когда кто-то использует эти слова или фразы в Zulip",
"All streams": "Все каналы", "All streams": "Все каналы",
"Allow subdomains": "", "Allow subdomains": "Разрешать поддомены",
"Allowed domains": "Разрешенные домены", "Allowed domains": "Разрешенные домены",
"Already subscribed to __stream__": "Уже подписан на __stream__", "Already subscribed to __stream__": "Уже подписан на __stream__",
"Always auto-scroll to new messages": "Всегда прокручивать к новым сообщениям", "Always auto-scroll to new messages": "Всегда прокручивать к новым сообщениям",
"An API key can be used to programmatically access a Zulip account. Anyone with access to your API key has the ability to read your messages, send messages on your behalf, and otherwise impersonate you on Zulip, so you should guard your API key as carefully as you guard your password. <br /> We recommend creating bots and using the bots' accounts and API keys to access the Zulip API, unless the task requires access to your account.": "", "An API key can be used to programmatically access a Zulip account. Anyone with access to your API key has the ability to read your messages, send messages on your behalf, and otherwise impersonate you on Zulip, so you should guard your API key as carefully as you guard your password. <br /> We recommend creating bots and using the bots' accounts and API keys to access the Zulip API, unless the task requires access to your account.": "API ключ может быть использован для программного доступа к аккаунту Zulip. Обладающий вашим API ключом имеет возможность читать ваши сообщения, посылать сообщения от вашего имени и иначе представлять вас в Zulip. Вам следует защищать API ключ так же как и ваш пароль. <br /> Мы рекомендуем использовать для ботов специальные аккаунты и API ключи для доступа к Zulip API, в случае если задача не требует доступа именно к вашему аккаунту.",
"An unknown error occurred.": "", "An unknown error occurred.": "Произошла неизвестная ошибка.",
"Announce stream": "Анонсировать новый канал", "Announce stream": "Анонсировать новый канал",
"Any user may now add new emoji!": "Теперь любой пользователь может добавлять эмодзи!", "Any user may now add new emoji!": "Теперь любой пользователь может добавлять эмодзи!",
"Any user may now create new streams!": "Любой пользователь теперь может создавать каналы!", "Any user may now create new streams!": "Любой пользователь теперь может создавать каналы!",
@@ -57,29 +57,29 @@
"Authentication methods saved!": "Способы аутентификации сохранены!", "Authentication methods saved!": "Способы аутентификации сохранены!",
"Author": "Автор", "Author": "Автор",
"Authorization methods": "", "Authorization methods": "",
"Base URL": "", "Base URL": "Базовый URL",
"Bot": "", "Bot": "Бот",
"Bot list": "", "Bot list": "Список ботов",
"Bot type": "", "Bot type": "Тип бота",
"Bringing you to your latest messages\u2026": "", "Bringing you to your latest messages\u2026": "",
"By deactivating <strong><span class=\"user_name\"></span></strong> &lt;<span class=\"email\"></span>&gt;, they will be logged out immediately.": "Если вы отключите учетную запись <strong><span class=\"user_name\"></span></strong> &lt;<span class=\"email\"></span>&gt;, они автоматически выйдут из системы.", "By deactivating <strong><span class=\"user_name\"></span></strong> &lt;<span class=\"email\"></span>&gt;, they will be logged out immediately.": "Если вы отключите учетную запись <strong><span class=\"user_name\"></span></strong> &lt;<span class=\"email\"></span>&gt;, они автоматически выйдут из системы.",
"By deactivating your account, you will be logged out immediately.": "Отключив свою учетную запись, вы автоматически выйдете из системы.", "By deactivating your account, you will be logged out immediately.": "Отключив свою учетную запись, вы автоматически выйдете из системы.",
"Cancel": "Отмена", "Cancel": "Отмена",
"Change": "", "Change": "Изменить",
"Change email": "", "Change email": "Изменить email",
"Change later messages to this topic": "Изменить последующие сообщения в этой теме", "Change later messages to this topic": "Изменить последующие сообщения в этой теме",
"Change notification settings for individual streams on your <a href=\"/#streams\">Streams page</a>.": "", "Change notification settings for individual streams on your <a href=\"/#streams\">Streams page</a>.": "",
"Change only this message topic": "Изменить тему только в этом сообщении", "Change only this message topic": "Изменить тему только в этом сообщении",
"Change password": "Изменить пароль", "Change password": "Изменить пароль",
"Change previous and following messages to this topic": "Изменить тему во всех сообщениях", "Change previous and following messages to this topic": "Изменить тему во всех сообщениях",
"Change stream privacy": "", "Change stream privacy": "",
"Changing email addresses has been disabled by your Zulip organization administrators. Contact an administrator for help.": "", "Changing email addresses has been disabled by your Zulip organization administrators. Contact an administrator for help.": "Смена email адресов была отключена администраторами Zulip вашей организации. Свяжитесь с ними для помощи.",
"Changing your name has been disabled by your Zulip organization administrators. Contact an administrator for help.": "", "Changing your name has been disabled by your Zulip organization administrators. Contact an administrator for help.": "Смена имен в была отключена администраторами Zulip вашей организации. Свяжитесь с ними для помощи.",
"Check all": "Выбрать все", "Check all": "Выбрать все",
"Choose custom color": "Выберите произвольный цвет", "Choose custom color": "Выберите произвольный цвет",
"Clear avatar": "Очистить аватар", "Clear avatar": "Очистить аватар",
"Clear emoji image": "", "Clear emoji image": "",
"Click here": "", "Click here": "Нажмите здесь",
"Close": "Закрыть", "Close": "Закрыть",
"Collapse": "Свернуть", "Collapse": "Свернуть",
"Compose a message to stream <b>__stream.name__</b>": "Написать сообщение в канал <b>__stream.name__</b>", "Compose a message to stream <b>__stream.name__</b>": "Написать сообщение в канал <b>__stream.name__</b>",
@@ -87,12 +87,12 @@
"Configure the authentication methods for your organization.": "", "Configure the authentication methods for your organization.": "",
"Configure the default streams new users are subscribed to when joining your organization.": "", "Configure the default streams new users are subscribed to when joining your organization.": "",
"Confirm password": "Подтвердите пароль", "Confirm password": "Подтвердите пароль",
"Cookie Bot": "", "Cookie Bot": "Cookie бот",
"Copied!": "", "Copied!": "Скопировано!",
"Copy and close": "", "Copy and close": "Скопировать и закрыть",
"Copy from stream": "", "Copy from stream": "Копировать из канала",
"Copy link to conversation": "", "Copy link to conversation": "Скопировать ссылку в беседу",
"Could not add user to this stream": "", "Could not add user to this stream": "Не удалось добавить пользователя в этот канал",
"Create": "Создать", "Create": "Создать",
"Create bot": "Создать бота", "Create bot": "Создать бота",
"Create new stream": "Создать новый поток", "Create new stream": "Создать новый поток",
@@ -101,27 +101,27 @@
"Custom emoji added!": "Дополнительный эмодзи добавлен!", "Custom emoji added!": "Дополнительный эмодзи добавлен!",
"Custom filter added!": "Дополнительный фильтр добавлен!", "Custom filter added!": "Дополнительный фильтр добавлен!",
"Customize avatar": "Настроить аватар", "Customize avatar": "Настроить аватар",
"Date uploaded": "", "Date uploaded": "Дата загрузки",
"Deactivate": "Отключить", "Deactivate": "Отключить",
"Deactivate account": "Отключить учетную запись", "Deactivate account": "Отключить учетную запись",
"Deactivate now": "Отключить сейчас", "Deactivate now": "Отключить сейчас",
"Deactivate stream": "", "Deactivate stream": "Отключить канал",
"Deactivate your account": "Отключить вашу учетную запись", "Deactivate your account": "Отключить вашу учетную запись",
"Deactivated users": "Отключенные пользователи", "Deactivated users": "Отключенные пользователи",
"Default language": "Язык по умолчанию", "Default language": "Язык по умолчанию",
"Default language changed!": "Язык по умолчанию изменен!", "Default language changed!": "Язык по умолчанию изменен!",
"Default streams": "Каналы по умолчанию", "Default streams": "Каналы по умолчанию",
"Delete alert word": "", "Delete alert word": "Удалить сигнальное слово",
"Delete avatar": "Удалить аватар", "Delete avatar": "Удалить аватар",
"Delete bot": "Удалить бота", "Delete bot": "Удалить бота",
"Delete draft": "", "Delete draft": "Удалить черновик",
"Delete file": "", "Delete file": "Удалить файл",
"Delete icon": "", "Delete icon": "",
"Delete message": "", "Delete message": "Удалить сообщение",
"Delete stream": "Удалить канал", "Delete stream": "Удалить канал",
"Deleted successfully!": "", "Deleted successfully!": "Удалено успешно!",
"Deleting this stream will immediately unsubscribe everyone, and the stream's content will not be recoverable.": "Удаление этого канала моментально отпишет от него всех участников, а сообщения в канале будут безвозвратно удалены.", "Deleting this stream will immediately unsubscribe everyone, and the stream's content will not be recoverable.": "Удаление этого канала моментально отпишет от него всех участников, а сообщения в канале будут безвозвратно удалены.",
"Description changed!": "", "Description changed!": "Описание обновлено!",
"Desktop notifications": "Всплывающие оповещения", "Desktop notifications": "Всплывающие оповещения",
"Digest emails when I'm away": "Присылать дайджест на почту, когда меня нет на месте", "Digest emails when I'm away": "Присылать дайджест на почту, когда меня нет на месте",
"Disabled": "", "Disabled": "",
@@ -132,9 +132,9 @@
"Domain": "Домен", "Domain": "Домен",
"Download .zuliprc": "Скачать .zuliprc", "Download .zuliprc": "Скачать .zuliprc",
"Download config of all active outgoing webhook bots in Zulip Botserver format.": "", "Download config of all active outgoing webhook bots in Zulip Botserver format.": "",
"Download file": "", "Download file": "Скачать файл",
"Download flaskbotrc": "", "Download flaskbotrc": "",
"Drafts": "", "Drafts": "Черновики",
"EDITED": "ИЗМЕНЕНО", "EDITED": "ИЗМЕНЕНО",
"Edit": "Изменить", "Edit": "Изменить",
"Edit bot": "Изменить бота", "Edit bot": "Изменить бота",
@@ -152,20 +152,20 @@
"Enable message edit history": "", "Enable message edit history": "",
"Enabled": "Включено", "Enabled": "Включено",
"Enabled: __- setting_name__": "", "Enabled: __- setting_name__": "",
"Error adding alert word!": "", "Error adding alert word!": "Ошибка добавления сигнального слова!",
"Error adding subscription": "Ошибка добавления подписки", "Error adding subscription": "Ошибка добавления подписки",
"Error changing emojiset.": "", "Error changing emojiset.": "",
"Error changing settings": "Ошибка изменения настроек", "Error changing settings": "Ошибка изменения настроек",
"Error checking subscription": "Ошибка проверки подписки", "Error checking subscription": "Ошибка проверки подписки",
"Error creating stream": "Ошибка создания канала", "Error creating stream": "Ошибка создания канала",
"Error deactivating account": "Ошибка отключения учетной записи", "Error deactivating account": "Ошибка отключения учетной записи",
"Error deleting message.": "", "Error deleting message.": "Ошибка удаления сообщения",
"Error fetching message edit history": "", "Error fetching message edit history": "",
"Error getting API key": "Ошибка получения API-ключа", "Error getting API key": "Ошибка получения API-ключа",
"Error listing users or bots": "Ошибка получения списка пользователей или ботов", "Error listing users or bots": "Ошибка получения списка пользователей или ботов",
"Error removing alert word!": "", "Error removing alert word!": "",
"Error removing subscription": "Ошибка удаления подписки", "Error removing subscription": "Ошибка удаления подписки",
"Error removing user from this stream": "", "Error removing user from this stream": "Ошибка исключения пользователя из канала",
"Error renaming stream": "Ошибка переименования канала", "Error renaming stream": "Ошибка переименования канала",
"Error saving edit": "", "Error saving edit": "",
"Error updating default language setting": "Ошибка обновления настройки языка по умолчанию", "Error updating default language setting": "Ошибка обновления настройки языка по умолчанию",
@@ -173,7 +173,7 @@
"Error updating high contrast setting": "", "Error updating high contrast setting": "",
"Error updating the stream description": "Ошибка обновления описания канала", "Error updating the stream description": "Ошибка обновления описания канала",
"Error updating time format setting": "Ошибка обновления настроек формата времени", "Error updating time format setting": "Ошибка обновления настроек формата времени",
"Error updating time zone": "", "Error updating time zone": "Ошибка обновления временной зоны",
"Error updating user list placement setting": "Ошибка обновления настройки положения списка пользователей", "Error updating user list placement setting": "Ошибка обновления настройки положения списка пользователей",
"Error updating: __- setting_name__": "", "Error updating: __- setting_name__": "",
"Failed": "Не удалось", "Failed": "Не удалось",
@@ -181,15 +181,15 @@
"Failed to generate preview": "Не удалось создать эскиз", "Failed to generate preview": "Не удалось создать эскиз",
"Failed!": "Не удалось!", "Failed!": "Не удалось!",
"Features for the brave. Labs features may change, break, or disappear at any time.": "", "Features for the brave. Labs features may change, break, or disappear at any time.": "",
"File": "", "File": "Файл",
"File type is not supported.": "", "File type is not supported.": "Тип файла не поддерживается",
"File upload is not yet available for your browser.": "", "File upload is not yet available for your browser.": "",
"Filter": "Фильтр", "Filter": "Фильтр",
"Filter bots": "", "Filter bots": "Фильтровать ботов",
"Filter deactivated users": "", "Filter deactivated users": "Фильтровать отключенных пользователей",
"Filter settings": "", "Filter settings": "Настройки фильтров",
"Filter streams": "Отфильтровать каналы", "Filter streams": "Отфильтровать каналы",
"Filter users": "", "Filter users": "Фильтровать пользователей",
"First time? Read our <a href=\"/help/create-a-stream\" target=\"_blank\">guidelines</a> for creating and naming streams.": "", "First time? Read our <a href=\"/help/create-a-stream\" target=\"_blank\">guidelines</a> for creating and naming streams.": "",
"For more information on public/private streams, check out our <a href=\"http://zulip.readthedocs.io/en/latest/security-model.html?highlight=private%20stream#messages-and-history\">docs</a>.": "", "For more information on public/private streams, check out our <a href=\"http://zulip.readthedocs.io/en/latest/security-model.html?highlight=private%20stream#messages-and-history\">docs</a>.": "",
"Forgotten it?": "Забыли?", "Forgotten it?": "Забыли?",
@@ -198,9 +198,9 @@
"Generate new API key": "Сгенерировать новый API-ключ", "Generate new API key": "Сгенерировать новый API-ключ",
"Generic bot": "", "Generic bot": "",
"Get API key": "Получить API-ключ", "Get API key": "Получить API-ключ",
"Go back": "", "Go back": "Вернуться",
"Got it!": "", "Got it!": "Понял!",
"High contrast mode": "", "High contrast mode": "Высоко-контрастный режим",
"High contrast mode __enabled_or_disabled__!": "", "High contrast mode __enabled_or_disabled__!": "",
"Home": "Главная", "Home": "Главная",
"I want:": "Я хочу:", "I want:": "Я хочу:",
@@ -210,23 +210,23 @@
"If checked, only administrators may invite new users.": "Если опция включена, только администраторы могут приглашать новых пользователей.", "If checked, only administrators may invite new users.": "Если опция включена, только администраторы могут приглашать новых пользователей.",
"If checked, only users with an e-mail address ending in these domains will be able to join the organization.": "Если опция включена, только пользователи с адресами email заканчивающимися на эти домены смогут присоединиться к организации.", "If checked, only users with an e-mail address ending in these domains will be able to join the organization.": "Если опция включена, только пользователи с адресами email заканчивающимися на эти домены смогут присоединиться к организации.",
"If checked, previews of linked websites will be shown.": "", "If checked, previews of linked websites will be shown.": "",
"If checked, topics are required.": "", "If checked, topics are required.": "Если опция включена, темы необходимы",
"If checked, users can edit the content and topics of their old messages.": "Если опция включена, пользователи могут редактировать текст и темы своих старых сообщений.", "If checked, users can edit the content and topics of their old messages.": "Если опция включена, пользователи могут редактировать текст и темы своих старых сообщений.",
"If checked, users must be invited in order to join your organization.": "Если опция включена, пользователи должны быть приглашены, чтобы присоединиться к вашей организации.", "If checked, users must be invited in order to join your organization.": "Если опция включена, пользователи должны быть приглашены, чтобы присоединиться к вашей организации.",
"If checked, users will be able view message edit history.": "", "If checked, users will be able view message edit history.": "Если опция включена, пользователи смогут видеть историю редактирования сообщения.",
"If checked, users will be unable to change their email address.": "", "If checked, users will be unable to change their email address.": "Если опция включена, пользователи не смогут изменить свой email адрес.",
"If checked, users will be unable to change their name.": "", "If checked, users will be unable to change their name.": "Если опция включена, пользователи не смогут изменить свое имя.",
"If non-zero, users can edit their message for this many minutes after it is sent. If zero, users can edit all their past messages.": "Если не равно 0, пользователи могут редактировать свое сообщение только в течение этого количества минут после отправки. Если 0, пользователи могут редактировать все свои сообщения.", "If non-zero, users can edit their message for this many minutes after it is sent. If zero, users can edit all their past messages.": "Если не равно 0, пользователи могут редактировать свое сообщение только в течение этого количества минут после отправки. Если 0, пользователи могут редактировать все свои сообщения.",
"Image": "Изображение", "Image": "Изображение",
"Inactive bots": "", "Inactive bots": "Неактивные боты",
"Include content of private messages in desktop notifications": "Получать содержимое личных сообщений во всплывающих оповещениях", "Include content of private messages in desktop notifications": "Получать содержимое личных сообщений во всплывающих оповещениях",
"Incoming webhook": "", "Incoming webhook": "",
"Incoming webhooks can only send messages.": "", "Incoming webhooks can only send messages.": "",
"It's been a while! Since you were last here, you received <b>__unread_count__</b> new messages.": "С возвращением! Пока вас не было, для вас накопилось <b>__unread_count__</b> новых сообщений.", "It's been a while! Since you were last here, you received <b>__unread_count__</b> new messages.": "С возвращением! Пока вас не было, для вас накопилось <b>__unread_count__</b> новых сообщений.",
"Joining the organization": "", "Joining the organization": "Присоединение к организации",
"Keyboard shortcuts": "Горячие клавиши", "Keyboard shortcuts": "Горячие клавиши",
"Language &amp; notifications": "", "Language &amp; notifications": "",
"Language settings": "", "Language settings": "Языковые настройки",
"Large number of subscribers": "", "Large number of subscribers": "",
"Last active": "", "Last active": "",
"Last seen __hours__ hours ago": "", "Last seen __hours__ hours ago": "",
@@ -236,37 +236,37 @@
"Last seen on __last_active__": "", "Last seen on __last_active__": "",
"Last seen on __last_active_date__": "", "Last seen on __last_active_date__": "",
"Last seen yesterday": "", "Last seen yesterday": "",
"Local time": "", "Local time": "Местное время",
"Looking for our <a href=\"/integrations\" target=\"_blank\">Integrations</a> or <a href=\"/api\" target=\"_blank\">API</a> documentation?": "", "Looking for our <a href=\"/integrations\" target=\"_blank\">Integrations</a> or <a href=\"/api\" target=\"_blank\">API</a> documentation?": "",
"Make admin": "Сделать администратором", "Make admin": "Сделать администратором",
"Make stream invite-only": "", "Make stream invite-only": "",
"Make stream public": "Сделать канал открытым", "Make stream public": "Сделать канал открытым",
"Make this message take up less space on the screen": "Сделать так, чтобы это сообщение занимало меньше места на экране", "Make this message take up less space on the screen": "Сделать так, чтобы это сообщение занимало меньше места на экране",
"Manage organization": "", "Manage organization": "Управление организацией",
"Mark all messages in <b>__stream.name__</b> as read": "Отметить все сообщения в <b>__stream.name__</b> как прочитанные", "Mark all messages in <b>__stream.name__</b> as read": "Отметить все сообщения в <b>__stream.name__</b> как прочитанные",
"Mark all messages in <b>__topic_name__</b> as read": "Отметить все сообщения в <b>__topic_name__</b> как прочитанные", "Mark all messages in <b>__topic_name__</b> as read": "Отметить все сообщения в <b>__topic_name__</b> как прочитанные",
"Mentioned in": "", "Mentioned in": "Упомянут в",
"Message actions": "", "Message actions": "",
"Message edit limit in minutes (0 for no limit)": "Лимит редактирования сообщений в минутах (0 - нет лимита)", "Message edit limit in minutes (0 for no limit)": "Лимит редактирования сообщений в минутах (0 - нет лимита)",
"Message editing": "Редактирование сообщений", "Message editing": "Редактирование сообщений",
"Message feed": "", "Message feed": "Поток сообщений",
"Message formatting": "Форматирование сообщений", "Message formatting": "Форматирование сообщений",
"Message sent when you were not subscribed": "Сообщение было отправлено, когда вы были не подписаны на канал", "Message sent when you were not subscribed": "Сообщение было отправлено, когда вы были не подписаны на канал",
"Message successfully edited!": "", "Message successfully edited!": "Сообщение успешно отредактировано!",
"Messages older than the configured number of days will be automatically deleted": "", "Messages older than the configured number of days will be automatically deleted": "",
"Messages retention period in days (blank means messages are retained forever)": "", "Messages retention period in days (blank means messages are retained forever)": "",
"Method": "Метод", "Method": "Метод",
"Mobile push notifications": "", "Mobile push notifications": "Мобильные push-оповещения",
"Mobile push notifications always (even when online)": "Всегда отправлять мобильные push-оповещения (даже когда пользователь онлайн)", "Mobile push notifications always (even when online)": "Всегда отправлять мобильные push-оповещения (даже когда пользователь онлайн)",
"Mobile push notifications when offline": "Отправлять мобильные push-оповещения, когда пользователь оффлайн", "Mobile push notifications when offline": "Отправлять мобильные push-оповещения, когда пользователь оффлайн",
"Most stream administration is done on the <a href=\"/#streams\">Streams page</a>.": "", "Most stream administration is done on the <a href=\"/#streams\">Streams page</a>.": "",
"Mute stream": "", "Mute stream": "Заглушить канал",
"Mute the stream <b>__stream.name__</b>": "Заглушить поток <b>__stream.name__</b>", "Mute the stream <b>__stream.name__</b>": "Заглушить поток <b>__stream.name__</b>",
"Mute the topic <b>__subject__</b>": "Заглушить тему <b>__subject__</b>", "Mute the topic <b>__subject__</b>": "Заглушить тему <b>__subject__</b>",
"Mute the topic <b>__topic_name__</b>": "Выключить оповещения из темы <b>__topic_name__</b>", "Mute the topic <b>__topic_name__</b>": "Выключить оповещения из темы <b>__topic_name__</b>",
"Mute topic": "", "Mute topic": "Заглушить тему",
"Muted streams don't show up in your home view or generate notifications unless you are mentioned.": "Приглушенные каналы не показываются в общем списке сообщений и не присылают оповещений, за исключением случаев, когда вас упомянули.", "Muted streams don't show up in your home view or generate notifications unless you are mentioned.": "Приглушенные каналы не показываются в общем списке сообщений и не присылают оповещений, за исключением случаев, когда вас упомянули.",
"Muted topics": "", "Muted topics": "Заглушенные темы",
"Name": "Имя", "Name": "Имя",
"Name changed!": "Название обновлено!", "Name changed!": "Название обновлено!",
"Narrow to stream &quot;__display_recipient__&quot;": "Показать только канал &quot;__display_recipient__&quot;", "Narrow to stream &quot;__display_recipient__&quot;": "Показать только канал &quot;__display_recipient__&quot;",
@@ -274,7 +274,7 @@
"Narrow to stream <b>__stream.name__</b>": "Показать только сообщения канала <b>__stream.name__</b>", "Narrow to stream <b>__stream.name__</b>": "Показать только сообщения канала <b>__stream.name__</b>",
"Narrow to topic <b>__topic_name__</b>": "Показать только тему <b>__topic_name__</b>", "Narrow to topic <b>__topic_name__</b>": "Показать только тему <b>__topic_name__</b>",
"Narrow to your private messages with __display_reply_to__": "Показать только личную переписку с __display_reply_to__", "Narrow to your private messages with __display_reply_to__": "Показать только личную переписку с __display_reply_to__",
"Never": "", "Never": "Никогда",
"Never had one? Forgotten it?": "", "Never had one? Forgotten it?": "",
"New alert word": "Новое сигнальное слово", "New alert word": "Новое сигнальное слово",
"New password": "Новый пароль", "New password": "Новый пароль",
@@ -284,41 +284,41 @@
"New users must be invited by an admin!": "Новые пользователи должны быть приглашены администратором!", "New users must be invited by an admin!": "Новые пользователи должны быть приглашены администратором!",
"New users must be invited by e-mail!": "Новых пользователей нужно пригласить по email!", "New users must be invited by e-mail!": "Новых пользователей нужно пригласить по email!",
"No": "Нет", "No": "Нет",
"No bots match your current filter.": "", "No bots match your current filter.": "Нет ботов попадающих под текущий фильтр.",
"No changes made.": "", "No changes made.": "Изменений не сделано.",
"No changes to save!": "Нет изменений для сохранения!", "No changes to save!": "Нет изменений для сохранения!",
"No default streams match you current filter.": "", "No default streams match you current filter.": "Нет каналов по умолчанию, попадающих под текущий фильтр.",
"No description.": "Нет описания.", "No description.": "Нет описания.",
"No drafts.": "", "No drafts.": "Нет черновиков.",
"No more topics.": "", "No more topics.": "",
"No streams match your current filter.": "", "No streams match your current filter.": "Нет каналов попадающих под текущий фильтр.",
"No users match your current filter.": "", "No users match your current filter.": "Нет пользователей попадающих под текущий фильтр.",
"None": "Пусто", "None": "Пусто",
"Note that any bots that you maintain will be disabled.": "Обратите внимание, все ваши боты будут отключены.", "Note that any bots that you maintain will be disabled.": "Обратите внимание, все ваши боты будут отключены.",
"Nothing to preview": "Пустое сообщение", "Nothing to preview": "Пустое сообщение",
"Notifications": "Оповещения", "Notifications": "Оповещения",
"Notifications are triggered when a message arrives and Zulip isn't in focus or the message is offscreen.": "", "Notifications are triggered when a message arrives and Zulip isn't in focus or the message is offscreen.": "",
"Notifications stream changed!": "", "Notifications stream changed!": "Оповещения канала изменены!",
"Notifications stream disabled!": "", "Notifications stream disabled!": "Оповещения канала отключены!",
"Notifications stream:": "", "Notifications stream:": "",
"Old password": "Старый пароль", "Old password": "Старый пароль",
"Only administrators may now add new emoji!": "", "Only administrators may now add new emoji!": "",
"Only administrators may now create new streams!": "", "Only administrators may now create new streams!": "",
"Only admins can invite new users": "", "Only admins can invite new users": "Только администраторы могут приглашать новых пользователей",
"Only organization administrators can add custom emoji in this organization.": "", "Only organization administrators can add custom emoji in this organization.": "",
"Only organization administrators can edit these settings.": "", "Only organization administrators can edit these settings.": "",
"Optional": "Необязательно", "Optional": "Необязательно",
"Organization": "", "Organization": "Организация",
"Organization avatar": "", "Organization avatar": "Аватар организации",
"Organization permissions": "", "Organization permissions": "",
"Organization profile": "", "Organization profile": "Профиль организации",
"Organization settings": "Настройки организации", "Organization settings": "Настройки организации",
"Other notifications I want:": "Другие оповещения:", "Other notifications I want:": "Другие оповещения:",
"Outgoing webhook": "", "Outgoing webhook": "",
"Outgoing webhook message format": "", "Outgoing webhook message format": "",
"Owner": "Владелец", "Owner": "Владелец",
"Password": "Пароль", "Password": "Пароль",
"Password is too weak": "", "Password is too weak": "Пароль слишком простой",
"Password should be at least __length__ characters long": "", "Password should be at least __length__ characters long": "",
"Pattern": "Шаблон", "Pattern": "Шаблон",
"People to add": "Кого добавить", "People to add": "Кого добавить",
@@ -332,7 +332,7 @@
"Prevent users from adding custom emoji": "", "Prevent users from adding custom emoji": "",
"Prevent users from changing their email address": "", "Prevent users from changing their email address": "",
"Prevent users from changing their name": "", "Prevent users from changing their name": "",
"Prevent users from creating streams": "", "Prevent users from creating streams": "Запретить пользователям создавать каналы",
"Previews for linked websites will be shown!": "", "Previews for linked websites will be shown!": "",
"Previews for linked websites will not be shown!": "", "Previews for linked websites will not be shown!": "",
"Previews of uploaded and linked images will be shown!": "", "Previews of uploaded and linked images will be shown!": "",
@@ -381,7 +381,7 @@
"Stream messages": "Сообщения канала", "Stream messages": "Сообщения канала",
"Stream name": "Имя канала", "Stream name": "Имя канала",
"Stream settings": "Настройки канала", "Stream settings": "Настройки канала",
"Streams": "Потоки", "Streams": "Каналы",
"Streams & custom emoji": "", "Streams & custom emoji": "",
"Subscribe": "Подписаться", "Subscribe": "Подписаться",
"Subscribe to __stream__": "Подписаться на __stream__", "Subscribe to __stream__": "Подписаться на __stream__",

View File

@@ -4,12 +4,10 @@
<div class="pitch"> <div class="pitch">
<hr/> <hr/>
<p class="lead">Whoops. The confirmation link has expired.</p> <p class="lead">Whoops. The confirmation link has expired or been deactivated.</p>
<p> <p>
If you're not sure how to generate a new one, shoot us a line at Please contact your organization administrator for a new one.
<a href="mailto:{{ support_email }}">{{ support_email }}</a>
and we'll get this resolved shortly.
</p> </p>
</div> </div>

View File

@@ -1,2 +1,2 @@
ZULIP_VERSION = "1.7.0" ZULIP_VERSION = "1.7.1"
PROVISION_VERSION = '10.7' PROVISION_VERSION = '10.7'

View File

@@ -3723,7 +3723,8 @@ def do_invite_users(user_profile, invitee_emails, streams, body=None):
# the PreregistrationUser objects and trigger the email invitations. # the PreregistrationUser objects and trigger the email invitations.
for email in validated_emails: for email in validated_emails:
# The logged in user is the referrer. # The logged in user is the referrer.
prereg_user = PreregistrationUser(email=email, referred_by=user_profile) prereg_user = PreregistrationUser(email=email, referred_by=user_profile,
realm=user_profile.realm)
prereg_user.save() prereg_user.save()
stream_ids = [stream.id for stream in streams] stream_ids = [stream.id for stream in streams]

View File

@@ -520,7 +520,7 @@ class GitHubAuthBackendTest(ZulipTestCase):
def test_github_backend_new_user(self): def test_github_backend_new_user(self):
# type: () -> None # type: () -> None
rf = RequestFactory() rf = RequestFactory()
request = rf.get('/complete') request = rf.get('/complete', HTTP_HOST=self.user_profile.realm.host)
request.session = {} request.session = {}
request.user = self.user_profile request.user = self.user_profile
self.backend.strategy.request = request self.backend.strategy.request = request

View File

@@ -62,7 +62,7 @@ class EmailChangeTestCase(ZulipTestCase):
type=Confirmation.EMAIL_CHANGE) type=Confirmation.EMAIL_CHANGE)
url = confirmation_url(key, user_profile.realm.host, Confirmation.EMAIL_CHANGE) url = confirmation_url(key, user_profile.realm.host, Confirmation.EMAIL_CHANGE)
response = self.client_get(url) response = self.client_get(url)
self.assert_in_success_response(["Whoops. The confirmation link has expired."], response) self.assert_in_success_response(["The confirmation link has expired or been deactivated."], response)
def test_confirm_email_change(self): def test_confirm_email_change(self):
# type: () -> None # type: () -> None

View File

@@ -324,7 +324,7 @@ class LoginTest(ZulipTestCase):
with queries_captured() as queries: with queries_captured() as queries:
self.register(self.nonreg_email('test'), "test") self.register(self.nonreg_email('test'), "test")
# Ensure the number of queries we make is not O(streams) # Ensure the number of queries we make is not O(streams)
self.assert_length(queries, 68) self.assert_length(queries, 70)
user_profile = self.nonreg_user('test') user_profile = self.nonreg_user('test')
self.assertEqual(get_session_dict_user(self.client.session), user_profile.id) self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
self.assertFalse(user_profile.enable_stream_desktop_notifications) self.assertFalse(user_profile.enable_stream_desktop_notifications)
@@ -925,7 +925,7 @@ class MultiuseInviteTest(ZulipTestCase):
result = self.client_post(invite_link, {'email': email}) result = self.client_post(invite_link, {'email': email})
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
self.assert_in_response("Whoops. The confirmation link has expired.", result) self.assert_in_response("The confirmation link has expired or been deactivated.", result)
def test_invalid_multiuse_link(self): def test_invalid_multiuse_link(self):
# type: () -> None # type: () -> None
@@ -1539,6 +1539,42 @@ class UserSignUpTest(ZulipTestCase):
mock_error.assert_called_once() mock_error.assert_called_once()
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
def test_replace_subdomain_in_confirmation_link(self) -> None:
"""
Check that manually changing the subdomain in a registration
confirmation link doesn't allow you to register to a different realm.
"""
email = "newuser@zulip.com"
self.client_post('/accounts/home/', {'email': email})
result = self.client_post(
'/accounts/register/',
{'password': "password",
'key': find_key_by_email(email),
'terms': True,
'full_name': "New User",
'from_confirmation': '1'}, subdomain="zephyr")
self.assert_in_success_response(["We couldn't find your confirmation link"], result)
def test_failed_signup_due_to_empty_realm_in_prereg_user(self) -> None:
"""
Largely to test a transitional state, where we started requiring the
realm in PreregistrationUser (if realm_creation is False), and wanted
to make sure we had properly disabled any existing confirmation links that
didn't have the realm set.
"""
email = "newuser@zulip.com"
password = "password"
self.client_post('/accounts/home/', {'email': email})
PreregistrationUser.objects.update(realm=None)
result = self.client_post(
'/accounts/register/',
{'password': password,
'key': find_key_by_email(email),
'terms': True,
'full_name': "New User",
'from_confirmation': '1'})
self.assert_in_success_response(["The confirmation link has expired or been deactivated."], result)
def test_failed_signup_due_to_restricted_domain(self): def test_failed_signup_due_to_restricted_domain(self):
# type: () -> None # type: () -> None
realm = get_realm('zulip') realm = get_realm('zulip')

View File

@@ -68,7 +68,7 @@ def maybe_send_to_registration(request, email, full_name='', password_required=T
prereg_user = None prereg_user = None
if settings.ONLY_SSO: if settings.ONLY_SSO:
try: try:
prereg_user = PreregistrationUser.objects.filter(email__iexact=email).latest("invited_at") prereg_user = PreregistrationUser.objects.filter(email__iexact=email, realm=realm).latest("invited_at")
except PreregistrationUser.DoesNotExist: except PreregistrationUser.DoesNotExist:
prereg_user = create_preregistration_user(email, request, prereg_user = create_preregistration_user(email, request,
password_required=password_required) password_required=password_required)

View File

@@ -77,15 +77,15 @@ def accounts_register(request):
password_required = prereg_user.password_required password_required = prereg_user.password_required
validators.validate_email(email) validators.validate_email(email)
if prereg_user.referred_by: if realm_creation:
# If someone invited you, you are joining their realm regardless
# of your e-mail address.
realm = prereg_user.referred_by.realm
elif realm_creation:
# For creating a new realm, there is no existing realm or domain # For creating a new realm, there is no existing realm or domain
realm = None realm = None
else: else:
realm = get_realm(get_subdomain(request)) realm = get_realm(get_subdomain(request))
if prereg_user.realm is None:
return render(request, 'confirmation/link_expired.html')
if prereg_user.realm != realm:
return render(request, 'confirmation/link_does_not_exist.html')
if realm and not email_allowed_for_realm(email, realm): if realm and not email_allowed_for_realm(email, realm):
return render(request, "zerver/closed_realm.html", return render(request, "zerver/closed_realm.html",
@@ -295,9 +295,13 @@ def login_and_go_to_home(request, user_profile):
def create_preregistration_user(email, request, realm_creation=False, def create_preregistration_user(email, request, realm_creation=False,
password_required=True): password_required=True):
# type: (Text, HttpRequest, bool, bool) -> HttpResponse # type: (Text, HttpRequest, bool, bool) -> HttpResponse
realm = None
if not realm_creation:
realm = get_realm(get_subdomain(request))
return PreregistrationUser.objects.create(email=email, return PreregistrationUser.objects.create(email=email,
realm_creation=realm_creation, realm_creation=realm_creation,
password_required=password_required) password_required=password_required,
realm=realm)
def send_registration_completion_email(email, request, realm_creation=False, streams=None): def send_registration_completion_email(email, request, realm_creation=False, streams=None):
# type: (str, HttpRequest, bool, Optional[List[Stream]]) -> None # type: (str, HttpRequest, bool, Optional[List[Stream]]) -> None