diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index b617ee6..b228cc8 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -5,6 +5,11 @@ if [ -n "${SNIKKET_SITE_NAME:-}" ]; then export SNIKKET_WEB_SITE_NAME="$SNIKKET_SITE_NAME" fi +export SNIKKET_WEB_TOS_URI="${SNIKKET_TOS_URI}" +export SNIKKET_WEB_PRIVACY_URI="${SNIKKET_PRIVACY_URI}" +export SNIKKET_WEB_ABUSE_EMAIL="${SNIKKET_ABUSE_EMAIL}" +export SNIKKET_WEB_SECURITY_EMAIL="${SNIKKET_SECURITY_EMAIL}" + export SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE="${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE-127.0.0.1}" export SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT="${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT-5765}" diff --git a/snikket_web/__init__.py b/snikket_web/__init__.py index 493fca3..53db150 100644 --- a/snikket_web/__init__.py +++ b/snikket_web/__init__.py @@ -170,6 +170,10 @@ class AppConfig: # tools may also very well override it. max_avatar_size = environ.var(1024*1024, converter=int) show_metrics = environ.bool_var(True) + tos_uri = environ.var("") + privacy_uri = environ.var("") + abuse_email = environ.var("") + security_email = environ.var("") _UPPER_CASE = "".join(map(chr, range(ord("A"), ord("Z")+1))) @@ -202,6 +206,10 @@ def create_app() -> quart.Quart: app.config["APPLE_STORE_URL"] = config.apple_store_url app.config["MAX_AVATAR_SIZE"] = config.max_avatar_size app.config["SHOW_METRICS"] = config.show_metrics + app.config["TOS_URI"] = config.tos_uri + app.config["PRIVACY_URI"] = config.privacy_uri + app.config["ABUSE_EMAIL"] = config.abuse_email + app.config["SECURITY_EMAIL"] = config.security_email app.context_processor(proc) app.register_error_handler( diff --git a/snikket_web/main.py b/snikket_web/main.py index 286ee1d..5a508a1 100644 --- a/snikket_web/main.py +++ b/snikket_web/main.py @@ -173,6 +173,42 @@ async def avatar(from_: str, code: str) -> quart.Response: return response +@bp.route("/terms") +async def terms() -> Response: + if not current_app.config["TOS_URI"]: + return Response("", 404) + + return Response("", status=303, headers={ + "Location": current_app.config["TOS_URI"], + }) + + +@bp.route("/privacy") +async def privacy() -> Response: + if not current_app.config["PRIVACY_URI"]: + return Response("", 404) + + return Response("", status=303, headers={ + "Location": current_app.config["PRIVACY_URI"], + }) + + +# This is linked from the iOS app and about page +@bp.route("/policies/") +async def policies() -> str: + return await render_template( + "policies.html", + ) + + +@bp.route("/.well-known/security.txt") +async def securitytxt() -> Response: + return Response( + await render_template("security.txt"), + mimetype="text/plain;charset=UTF-8", + ) + + @bp.route("/_health") async def health() -> Response: return Response("STATUS OK", content_type="text/plain") diff --git a/snikket_web/templates/about.html b/snikket_web/templates/about.html index b6e4b05..0f32c8f 100644 --- a/snikket_web/templates/about.html +++ b/snikket_web/templates/about.html @@ -6,16 +6,20 @@ {% block body %}
-

{% trans %}About Snikket{% endtrans %}

-

{% trans snikket_url="https://snikket.org" %}To learn more about Snikket, visit the Snikket website.{% endtrans %}

{% trans %}About this Service{% endtrans %}

-

{% trans site_name=config["SITE_NAME"] %}This is the Snikket service {{ site_name }}.{% endtrans %}

+

{% trans site_name=config["SITE_NAME"] %}This is the Snikket service {{ site_name }}, running open-source software from the Snikket project.{% endtrans %}

+

{% trans snikket_url="https://snikket.org" %}To learn more about Snikket, visit the Snikket website.{% endtrans %}

+ +

{% trans %}View service policies{% endtrans %} +

{% trans %}Licenses{% endtrans %}

{% trans agpl_url="https://www.gnu.org/licenses/agpl.html" %}The web portal software is licensed under the terms of the Affero GNU General Public License, version 3.0 or later. The full terms of the license can be reviewed using the aforementioned link.{% endtrans %}

{% trans source_url="https://github.com/snikket-im/snikket-web-portal/" %}The source code of the web portal can be downloaded and viewed in its GitHub repository.{% endtrans %}

{% trans source_url="https://material.io/resources/icons/", apache20_url="https://www.apache.org/licenses/LICENSE-2.0.txt" %}The icons used in the web portal are Google’s Material Icons, made available by Google under the terms of the Apache 2.0 License.{% endtrans %}

+

{% trans %}Trademarks{% endtrans %}

{% trans trademarks_url="https://snikket.org/about/trademarks/" %}“Snikket” and the parrot logo are trademarks of Snikket Community Interest Company. For more information about the trademarks, visit the Snikket Trademarks information page.{% endtrans %} +

{% trans %}Software Versions{% endtrans %}

Domain: {{ config["SNIKKET_DOMAIN"] }}
 Web Portal{% if version %} ({{ version }}){% endif %}
@@ -27,6 +31,7 @@ Web Portal{% if version %} ({{ version }}){% endif %}
 {% for name, version in extra_versions.items() %}
 {{ name }} ({{ version }}){% endfor %}
 {%- endif -%}
+

{%- call standard_button("back", url_for("index"), class="primary") -%} {% trans %}Back to the main page{% endtrans %} diff --git a/snikket_web/templates/invite_view.html b/snikket_web/templates/invite_view.html index 45d08f7..1e6089a 100644 --- a/snikket_web/templates/invite_view.html +++ b/snikket_web/templates/invite_view.html @@ -17,6 +17,13 @@ {%- else -%}

{% trans site_name=config["SITE_NAME"] %}You have been invited to chat on {{ site_name }} using Snikket, a secure, privacy-friendly chat app.{% endtrans %}

{%- endif -%} + + {%- if config["TOS_URI"] and config["PRIVACY_URI"] -%} +

+ {% trans site_name=config["SITE_NAME"], tos_uri=config["TOS_URI"], privacy_uri=config["PRIVACY_URI"] %}By continuing, you agree to the Terms of Service and Privacy Policy.{% endtrans %} +

+ {%- endif -%} +

{% trans %}Get started{% endtrans %}

{%- if apple_store_url -%}

{% trans %}Install the Snikket App on your Android or iOS device.{% endtrans %}

diff --git a/snikket_web/templates/policies.html b/snikket_web/templates/policies.html new file mode 100644 index 0000000..bebfdf6 --- /dev/null +++ b/snikket_web/templates/policies.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% from "library.j2" import standard_button %} +{% block head_lead %} +{% trans %}Policies{% endtrans %} - {{ config["SITE_NAME"] }} +{% endblock %} +{% block body %} +
+
+

{{ config["SITE_NAME"] }}

+

{% trans %}Policies{% endtrans %}

+ + {% if config["TOS_URI"] or config["PRIVACY_URI"] -%} +

{% trans %}Use of this service is subject to the following policies:{% endtrans %}

+ + {%- else -%} +

{% trans %}Please contact the administrator of this instance if you have questions about policies.{% endtrans %}

+ {% endif -%} + +

{% trans url="https://snikket.org/app/privacy/" %}Use of the Snikket apps is subject to the Snikket Apps Privacy Policy.{% endtrans %}

+ + {%- if config["ABUSE_EMAIL"] %} +

{% trans email=config["ABUSE_EMAIL"], domain=config["SNIKKET_DOMAIN"] %}To report policy violations or other abuse from this service, please send an email to {{email}}. Specify the domain name of this instance ({{domain}}) and include details of the incident(s).{% endtrans %}

+ {%- endif %} + +

+ {%- call standard_button("back", url_for("index"), class="primary") -%} + {% trans %}Back to the main page{% endtrans %} + {%- endcall -%} +

+
+
+{% endblock %} diff --git a/snikket_web/templates/security.txt b/snikket_web/templates/security.txt new file mode 100644 index 0000000..26d7554 --- /dev/null +++ b/snikket_web/templates/security.txt @@ -0,0 +1,16 @@ +# {{ config["SNIKKET_DOMAIN"] }} is running open-source software +# from the Snikket project: https://snikket.org/ + +{% if config["SECURITY_EMAIL"] -%} +# Security issues related to this service should be addressed to the +# following security contact: +Contact: mailto:{{ config["SECURITY_EMAIL"] }} +{% else -%} +# This service does not have a public security contact. You might find +# more information about the service at the following link: +Contact: https://{{ config["SNIKKET_DOMAIN"] }}/policies/ +{%- endif %} + +# Please report software defects to the project developers, per the +# instructions at the following link: +Contact: https://snikket.org/security/ diff --git a/snikket_web/translations/da/LC_MESSAGES/messages.mo b/snikket_web/translations/da/LC_MESSAGES/messages.mo index 17f4c5d..e0c0b6c 100644 Binary files a/snikket_web/translations/da/LC_MESSAGES/messages.mo and b/snikket_web/translations/da/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/de/LC_MESSAGES/messages.mo b/snikket_web/translations/de/LC_MESSAGES/messages.mo index a0a0f40..481c919 100644 Binary files a/snikket_web/translations/de/LC_MESSAGES/messages.mo and b/snikket_web/translations/de/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/en/LC_MESSAGES/messages.mo b/snikket_web/translations/en/LC_MESSAGES/messages.mo index 02e3a2b..0088b98 100644 Binary files a/snikket_web/translations/en/LC_MESSAGES/messages.mo and b/snikket_web/translations/en/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/en_GB/LC_MESSAGES/messages.mo b/snikket_web/translations/en_GB/LC_MESSAGES/messages.mo index 25c46bf..1557d2b 100644 Binary files a/snikket_web/translations/en_GB/LC_MESSAGES/messages.mo and b/snikket_web/translations/en_GB/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/es_MX/LC_MESSAGES/messages.mo b/snikket_web/translations/es_MX/LC_MESSAGES/messages.mo index dc5bb49..f054855 100644 Binary files a/snikket_web/translations/es_MX/LC_MESSAGES/messages.mo and b/snikket_web/translations/es_MX/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/fr/LC_MESSAGES/messages.mo b/snikket_web/translations/fr/LC_MESSAGES/messages.mo index 1a05347..74ee591 100644 Binary files a/snikket_web/translations/fr/LC_MESSAGES/messages.mo and b/snikket_web/translations/fr/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/id/LC_MESSAGES/messages.mo b/snikket_web/translations/id/LC_MESSAGES/messages.mo index cfa9ecd..6d4ea2c 100644 Binary files a/snikket_web/translations/id/LC_MESSAGES/messages.mo and b/snikket_web/translations/id/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/it/LC_MESSAGES/messages.mo b/snikket_web/translations/it/LC_MESSAGES/messages.mo index 23a6e95..7dfed65 100644 Binary files a/snikket_web/translations/it/LC_MESSAGES/messages.mo and b/snikket_web/translations/it/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/messages.pot b/snikket_web/translations/messages.pot index 8eee3ef..b154298 100644 --- a/snikket_web/translations/messages.pot +++ b/snikket_web/translations/messages.pot @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-04-01 10:07+0200\n" +"POT-Creation-Date: 2023-10-25 16:15+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.12.1\n" +"Generated-By: Babel 2.13.1\n" #: snikket_web/admin.py:69 snikket_web/templates/admin_delete_user.html:10 #: snikket_web/templates/admin_edit_circle.html:59 @@ -382,31 +382,37 @@ msgid "" "Interest Company." msgstr "" -#: snikket_web/templates/about.html:4 snikket_web/templates/about.html:9 +#: snikket_web/templates/about.html:4 msgid "About Snikket" msgstr "" +#: snikket_web/templates/about.html:9 +msgid "About this Service" +msgstr "" + #: snikket_web/templates/about.html:10 #, python-format msgid "" +"This is the Snikket service %(site_name)s, running open-source " +"software from the Snikket project." +msgstr "" + +#: snikket_web/templates/about.html:11 +#, python-format +msgid "" "To learn more about Snikket, visit the Snikket website." msgstr "" -#: snikket_web/templates/about.html:11 -msgid "About this Service" -msgstr "" - -#: snikket_web/templates/about.html:12 -#, python-format -msgid "This is the Snikket service %(site_name)s." -msgstr "" - #: snikket_web/templates/about.html:13 +msgid "View service policies" +msgstr "" + +#: snikket_web/templates/about.html:15 msgid "Licenses" msgstr "" -#: snikket_web/templates/about.html:14 +#: snikket_web/templates/about.html:16 #, python-format msgid "" "The web portal software is licensed under the terms of the its GitHub repository." msgstr "" -#: snikket_web/templates/about.html:16 +#: snikket_web/templates/about.html:18 #, python-format msgid "" "The icons used in the web portal are Google’s " @@ -430,11 +436,11 @@ msgid "" "href=\"%(apache20_url)s\">Apache 2.0 License." msgstr "" -#: snikket_web/templates/about.html:17 +#: snikket_web/templates/about.html:20 msgid "Trademarks" msgstr "" -#: snikket_web/templates/about.html:18 +#: snikket_web/templates/about.html:21 #, python-format msgid "" "“Snikket” and the parrot logo are trademarks of Snikket Community " @@ -442,11 +448,11 @@ msgid "" " href=\"%(trademarks_url)s\">Snikket Trademarks information page." msgstr "" -#: snikket_web/templates/about.html:19 +#: snikket_web/templates/about.html:23 msgid "Software Versions" msgstr "" -#: snikket_web/templates/about.html:32 +#: snikket_web/templates/about.html:37 snikket_web/templates/policies.html:34 msgid "Back to the main page" msgstr "" @@ -1093,20 +1099,20 @@ msgid "" msgstr "" #: snikket_web/templates/invite_register.html:14 -#: snikket_web/templates/invite_view.html:39 +#: snikket_web/templates/invite_view.html:46 msgid "App already installed?" msgstr "" #: snikket_web/templates/invite_register.html:16 #: snikket_web/templates/invite_reset_view.html:21 -#: snikket_web/templates/invite_view.html:41 -#: snikket_web/templates/invite_view.html:84 -#: snikket_web/templates/invite_view.html:112 +#: snikket_web/templates/invite_view.html:48 +#: snikket_web/templates/invite_view.html:91 +#: snikket_web/templates/invite_view.html:119 msgid "Open the app" msgstr "" #: snikket_web/templates/invite_register.html:18 -#: snikket_web/templates/invite_view.html:43 +#: snikket_web/templates/invite_view.html:50 msgid "This button works only if you have the app installed already!" msgstr "" @@ -1202,7 +1208,7 @@ msgid "You will then be prompted to enter a new password for your account." msgstr "" #: snikket_web/templates/invite_reset_view.html:29 -#: snikket_web/templates/invite_view.html:45 +#: snikket_web/templates/invite_view.html:52 msgid "Alternatives" msgstr "" @@ -1288,15 +1294,22 @@ msgid "" "privacy-friendly chat app." msgstr "" -#: snikket_web/templates/invite_view.html:20 +#: snikket_web/templates/invite_view.html:23 +#, python-format +msgid "" +"By continuing, you agree to the Terms of " +"Service and Privacy Policy." +msgstr "" + +#: snikket_web/templates/invite_view.html:27 msgid "Get started" msgstr "" -#: snikket_web/templates/invite_view.html:22 +#: snikket_web/templates/invite_view.html:29 msgid "Install the Snikket App on your Android or iOS device." msgstr "" -#: snikket_web/templates/invite_view.html:24 +#: snikket_web/templates/invite_view.html:31 #, python-format msgid "" "Install the Snikket App on your Android device (iOS coming soon!)." msgstr "" -#: snikket_web/templates/invite_view.html:28 +#: snikket_web/templates/invite_view.html:35 msgid "Get it on Google Play" msgstr "" -#: snikket_web/templates/invite_view.html:30 -#: snikket_web/templates/invite_view.html:80 +#: snikket_web/templates/invite_view.html:37 +#: snikket_web/templates/invite_view.html:87 msgid "Download on the App Store" msgstr "" -#: snikket_web/templates/invite_view.html:32 +#: snikket_web/templates/invite_view.html:39 msgid "Get it on F-Droid" msgstr "" -#: snikket_web/templates/invite_view.html:35 +#: snikket_web/templates/invite_view.html:42 msgid "Send to mobile device" msgstr "" -#: snikket_web/templates/invite_view.html:38 +#: snikket_web/templates/invite_view.html:45 msgid "" "After installation the app should automatically open and prompt you to " "create an account. If not, simply click the button below." msgstr "" -#: snikket_web/templates/invite_view.html:46 +#: snikket_web/templates/invite_view.html:53 #, python-format msgid "" "You can connect to Snikket using any XMPP-compatible software. If the " @@ -1335,59 +1348,59 @@ msgid "" "href=\"%(register_url)s\">register an account manually." msgstr "" -#: snikket_web/templates/invite_view.html:52 +#: snikket_web/templates/invite_view.html:59 msgid "Scan invite code" msgstr "" -#: snikket_web/templates/invite_view.html:55 #: snikket_web/templates/invite_view.html:62 -#: snikket_web/templates/invite_view.html:74 -#: snikket_web/templates/invite_view.html:90 -#: snikket_web/templates/invite_view.html:102 -#: snikket_web/templates/invite_view.html:118 +#: snikket_web/templates/invite_view.html:69 +#: snikket_web/templates/invite_view.html:81 +#: snikket_web/templates/invite_view.html:97 +#: snikket_web/templates/invite_view.html:109 +#: snikket_web/templates/invite_view.html:125 msgid "Close" msgstr "" -#: snikket_web/templates/invite_view.html:58 +#: snikket_web/templates/invite_view.html:65 msgid "" "You can transfer this invite to your mobile device by scanning a code " "with your camera. You can use either a QR scanner app or the Snikket app " "itself." msgstr "" -#: snikket_web/templates/invite_view.html:71 +#: snikket_web/templates/invite_view.html:78 msgid "Install on iOS" msgstr "" -#: snikket_web/templates/invite_view.html:77 +#: snikket_web/templates/invite_view.html:84 msgid "" "After downloading Snikket from the App Store, you have to return to this " "invite link and tap on \"Open the app\" to proceed." msgstr "" -#: snikket_web/templates/invite_view.html:79 +#: snikket_web/templates/invite_view.html:86 msgid "First download Snikket from the App Store using the button below:" msgstr "" -#: snikket_web/templates/invite_view.html:81 -#: snikket_web/templates/invite_view.html:109 +#: snikket_web/templates/invite_view.html:88 +#: snikket_web/templates/invite_view.html:116 msgid "" "After the installation is complete, you can return to this page and tap " "the \"Open the app\" button to continue with the setup:" msgstr "" -#: snikket_web/templates/invite_view.html:99 -#: snikket_web/templates/invite_view.html:108 +#: snikket_web/templates/invite_view.html:106 +#: snikket_web/templates/invite_view.html:115 msgid "Install via F-Droid" msgstr "" -#: snikket_web/templates/invite_view.html:105 +#: snikket_web/templates/invite_view.html:112 msgid "" "After installing Snikket via F-Droid, you have to return to this invite " "link and tap on \"Open the app\" to proceed." msgstr "" -#: snikket_web/templates/invite_view.html:107 +#: snikket_web/templates/invite_view.html:114 msgid "First install Snikket from F-Droid using the button below:" msgstr "" @@ -1426,6 +1439,43 @@ msgid "" "@%(snikket_domain)s. Your password was not sent." msgstr "" +#: snikket_web/templates/policies.html:4 snikket_web/templates/policies.html:10 +msgid "Policies" +msgstr "" + +#: snikket_web/templates/policies.html:13 +msgid "Use of this service is subject to the following policies:" +msgstr "" + +#: snikket_web/templates/policies.html:16 +msgid "Terms of Service" +msgstr "" + +#: snikket_web/templates/policies.html:19 +msgid "Privacy Policy" +msgstr "" + +#: snikket_web/templates/policies.html:23 +msgid "" +"Please contact the administrator of this instance if you have questions " +"about policies." +msgstr "" + +#: snikket_web/templates/policies.html:26 +#, python-format +msgid "" +"Use of the Snikket apps is subject to the Snikket " +"Apps Privacy Policy." +msgstr "" + +#: snikket_web/templates/policies.html:29 +#, python-format +msgid "" +"To report policy violations or other abuse from this service, please send" +" an email to %(email)s. Specify the domain name of this instance " +"(%(domain)s) and include details of the incident(s)." +msgstr "" + #: snikket_web/templates/unauth.html:16 msgid "Operation successful" msgstr "" diff --git a/snikket_web/translations/pl/LC_MESSAGES/messages.mo b/snikket_web/translations/pl/LC_MESSAGES/messages.mo index bbd7178..7b5b189 100644 Binary files a/snikket_web/translations/pl/LC_MESSAGES/messages.mo and b/snikket_web/translations/pl/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/sv/LC_MESSAGES/messages.mo b/snikket_web/translations/sv/LC_MESSAGES/messages.mo index 224e463..af5ea52 100644 Binary files a/snikket_web/translations/sv/LC_MESSAGES/messages.mo and b/snikket_web/translations/sv/LC_MESSAGES/messages.mo differ diff --git a/snikket_web/translations/zh_Hans_CN/LC_MESSAGES/messages.mo b/snikket_web/translations/zh_Hans_CN/LC_MESSAGES/messages.mo index f23f675..6e1cc5f 100644 Binary files a/snikket_web/translations/zh_Hans_CN/LC_MESSAGES/messages.mo and b/snikket_web/translations/zh_Hans_CN/LC_MESSAGES/messages.mo differ