Merge branch 'main' into application-wizard-2-with-api-and-tests

* main: (23 commits)
  web/admin: use <pre> for order field on bound elements (#7031)
  blueprints: fix mismatched user-login stage order (#7030)
  stages/email: rework email templates (#7029)
  website/docs: add notice for nginx ingress configuration requirement (#7027)
  translate: Updates for web/xliff/en.xlf in fr
  web: locales: rename fr_FR to fr to match transifex
  events: fix error when storing events with date/time/datetime/etc (#7028)
  stages/invitation: fix mis-matched serializer class for invitation (#7018)
  web: bump mermaid from 10.4.0 to 10.5.0 in /web (#7026)
  web: bump core-js from 3.32.2 to 3.33.0 in /web (#7020)
  core: bump webauthn from 1.10.1 to 1.11.0 (#7021)
  core: bump pylint from 2.17.6 to 2.17.7 (#7022)
  core: bump django-redis from 5.3.0 to 5.4.0 (#7023)
  core: bump packaging from 23.1 to 23.2 (#7024)
  web/admin: invitation stage: default "continue without invitation" to false
  core: bump pydantic from 2.4.1 to 2.4.2 (#7014)
  website: bump postcss from 8.4.30 to 8.4.31 in /website (#7015)
  internal: fix redis session store (#7011)
  web: bump rollup from 3.29.3 to 3.29.4 in /web (#7009)
  core: bump github.com/prometheus/client_golang from 1.16.0 to 1.17.0 (#7007)
  ...
This commit is contained in:
Ken Sternberg 2023-10-02 08:41:06 -07:00
commit f564c9da73
32 changed files with 2386 additions and 572 deletions

View file

@ -9,6 +9,8 @@ lifecycle/ @goauthentik/backend
schemas/ @goauthentik/backend
scripts/ @goauthentik/backend
tests/ @goauthentik/backend
pyproject.toml @goauthentik/backend
poetry.lock @goauthentik/backend
# Infrastructure
.github/ @goauthentik/infrastructure
Dockerfile @goauthentik/infrastructure

View file

@ -6,6 +6,7 @@ from django.test import TestCase
from authentik.blueprints.v1.importer import is_model_allowed
from authentik.lib.models import SerializerModel
from authentik.providers.oauth2.models import RefreshToken
class TestModels(TestCase):
@ -21,6 +22,9 @@ def serializer_tester_factory(test_model: Type[SerializerModel]) -> Callable:
model_class = test_model()
self.assertTrue(isinstance(model_class, SerializerModel))
self.assertIsNotNone(model_class.serializer)
if model_class.serializer.Meta().model == RefreshToken:
return
self.assertEqual(model_class.serializer.Meta().model, test_model)
return tester

View file

@ -436,32 +436,39 @@ class NotificationTransport(SerializerModel):
def send_email(self, notification: "Notification") -> list[str]:
"""Send notification via global email configuration"""
subject = "authentik Notification: "
key_value = {
"user_email": notification.user.email,
"user_username": notification.user.username,
subject_prefix = "authentik Notification: "
context = {
"key_value": {
"user_email": notification.user.email,
"user_username": notification.user.username,
},
"body": notification.body,
"title": "",
}
if notification.event and notification.event.user:
key_value["event_user_email"] = notification.event.user.get("email", None)
key_value["event_user_username"] = notification.event.user.get("username", None)
context["key_value"]["event_user_email"] = notification.event.user.get("email", None)
context["key_value"]["event_user_username"] = notification.event.user.get(
"username", None
)
if notification.event:
subject += notification.event.action
context["title"] += notification.event.action
for key, value in notification.event.context.items():
if not isinstance(value, str):
continue
key_value[key] = value
context["key_value"][key] = value
else:
subject += notification.body[:75]
context["title"] += notification.body[:75]
# TODO: improve permission check
if notification.user.is_superuser:
context["source"] = {
"from": self.name,
}
mail = TemplateEmailMessage(
subject=subject,
subject=subject_prefix + context["title"],
to=[notification.user.email],
language=notification.user.locale(),
template_name="email/generic.html",
template_context={
"title": subject,
"body": notification.body,
"key_value": key_value,
},
template_name="email/event_notification.html",
template_context=context,
)
# Email is sent directly here, as the call to send() should have been from a task.
try:

View file

@ -2,6 +2,7 @@
import re
from copy import copy
from dataclasses import asdict, is_dataclass
from datetime import date, datetime, time, timedelta
from enum import Enum
from pathlib import Path
from types import GeneratorType
@ -13,6 +14,7 @@ from django.core.handlers.wsgi import WSGIRequest
from django.db import models
from django.db.models.base import Model
from django.http.request import HttpRequest
from django.utils import timezone
from django.views.debug import SafeExceptionReporterFilter
from geoip2.models import City
from guardian.utils import get_anonymous_user
@ -84,7 +86,7 @@ def get_user(user: User, original_user: Optional[User] = None) -> dict[str, Any]
return user_data
# pylint: disable=too-many-return-statements
# pylint: disable=too-many-return-statements,too-many-branches
def sanitize_item(value: Any) -> Any:
"""Sanitize a single item, ensure it is JSON parsable"""
if is_dataclass(value):
@ -134,6 +136,23 @@ def sanitize_item(value: Any) -> Any:
"type": value.__name__,
"module": value.__module__,
}
# See
# https://github.com/encode/django-rest-framework/blob/master/rest_framework/utils/encoders.py
# For Date Time string spec, see ECMA 262
# https://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
if isinstance(value, datetime):
representation = value.isoformat()
if representation.endswith("+00:00"):
representation = representation[:-6] + "Z"
return representation
if isinstance(value, date):
return value.isoformat()
if isinstance(value, time):
if timezone and timezone.is_aware(value):
raise ValueError("JSON can't represent timezone-aware times.")
return value.isoformat()
if isinstance(value, timedelta):
return str(value.total_seconds())
return value

View file

@ -1,205 +0,0 @@
/* authentik Email CSS */
* {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
box-sizing: border-box;
font-size: 14px;
}
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
width: 100% !important;
height: 100%;
line-height: 1.6em;
}
table td {
vertical-align: top;
}
body {
background-color: #f6f6f6;
}
.body-wrap {
background-color: #f6f6f6;
width: 100%;
}
.container {
display: block !important;
max-width: 600px !important;
margin: 0 auto !important;
clear: both !important;
}
.content {
max-width: 600px;
margin: 0 auto;
display: block;
padding: 20px;
}
.main {
background-color: #fff;
border: 1px solid #e9e9e9;
}
.content-wrap {
padding: 20px;
}
.content-block {
padding: 0 0 20px;
}
.header {
width: 100%;
margin-bottom: 20px;
}
.footer {
width: 100%;
clear: both;
color: #999;
padding: 20px;
}
.footer p, .footer a, .footer td {
color: #999;
font-size: 12px;
}
h1, h2, h3 {
font-family: Helvetica, Arial, sans-serif;
color: #000;
margin: 40px 0 0;
line-height: 1.2em;
font-weight: 400;
}
h1 {
font-size: 32px;
font-weight: 500;
}
h2 {
font-size: 24px;
}
h3 {
font-size: 18px;
}
h4 {
font-size: 14px;
font-weight: 600;
}
p, ul, ol {
margin-bottom: 10px;
font-weight: normal;
}
p li, ul li, ol li {
margin-left: 5px;
list-style-position: inside;
}
a {
color: #348eda;
text-decoration: underline;
}
.btn-primary {
text-decoration: none;
color: #FFF;
background-color: #348eda;
border: solid #348eda;
border-width: 10px 20px;
line-height: 2em;
font-weight: bold;
text-align: center;
cursor: pointer;
display: inline-block;
text-transform: capitalize;
}
.btn-primary a {
color: #fff;
}
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.clear {
clear: both;
}
.alert {
font-size: 16px;
color: #fff;
font-weight: 500;
padding: 20px;
text-align: center;
}
.alert a {
color: #fff;
text-decoration: none;
font-weight: 500;
font-size: 16px;
}
.alert-brand {
background-color: #fd4b2d;
}
.alert-warning {
background-color: #F0AB00;
}
.alert-danger {
background-color: #C9190B;
}
.alert-success {
background-color: #3E8635;
}
.body {
margin: 40px auto;
text-align: left;
width: 80%;
}
.body td {
padding: 5px 0;
}
.body .body-items {
width: 100%;
}
.body .body-items td {
border-top: #eee 1px solid;
}
.body .body-items .total td {
border-top: 2px solid #333;
border-bottom: 2px solid #333;
font-weight: 700;
}
@media only screen and (max-width: 640px) {
body {
padding: 0 !important;
}
h1, h2, h3, h4 {
font-weight: 800 !important;
margin: 20px 0 5px !important;
}
h1 {
font-size: 22px !important;
}
h2 {
font-size: 18px !important;
}
h3 {
font-size: 16px !important;
}
.container {
padding: 0 !important;
width: 100% !important;
}
.content {
padding: 0 !important;
}
.content-wrap {
padding: 10px !important;
}
.body {
width: 100% !important;
}
}

View file

@ -4,35 +4,38 @@
{% load i18n %}
{% block content %}
<td>
<h2>
{% trans 'Welcome!' %}
</h2>
<p>
{% trans "We're excited to have you get started. First, you need to confirm your account. Just press the button below."%}
</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="center">
<h1>
{% trans 'Welcome!' %}
</h1>
</td>
</tr>
<tr>
<td align="center">
<table border="0">
<tr>
<td align="center">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a id="confirm" href="{{ url }}" rel="noopener noreferrer" target="_blank">{% trans 'Confirm Account' %}</a> </td>
</tr>
</tbody>
</table>
<td align="center" style="max-width: 300px; padding: 20px 0; color: #212124;">
{% trans "We're excited to have you get started. First, you need to confirm your account. Just press the button below."%}
</td>
</tr>
</tbody>
</table>
<p>
<tr>
<td align="center" class="btn btn-primary">
<a id="confirm" href="{{ url }}" rel="noopener noreferrer" target="_blank">{% trans 'Confirm Account' %}</a>
</td>
</tr>
</table>
</td>
</tr>
<td>
{% endblock %}
{% block sub_content %}
<tr>
<td style="padding: 20px; font-size: 12px; color: #212124;word-break: break-all; overflow-wrap: break-word;" align="center">
{% blocktrans with url=url %}
If that doesn't work, copy and paste the following link in your browser: {{ url }}
{% endblocktrans %}
</p>
<p>
{% trans "If you have any questions, just reply to this email—we're always happy to help out." %}
</p>
</td>
</td>
</tr>
{% endblock %}

View file

@ -1,34 +1,131 @@
{% load authentik_stages_email %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
<style>{% inline_static_ascii "stages/email/css/base.css" %}</style>
</head>
<body itemscope itemtype="http://schema.org/EmailMessage">
<table class="body-wrap">
<html xmlns="http://www.w3.org/1999/xhtm=l">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body {
font-family: Arial, sans-serif;
font-size: 14px;
color: #212124;
}
h2 {
display: inline-block;
font-family: Arial, sans-serif;
font-size: 28px;
line-height: 125%;
font-weight: 700;
padding-top: 10px;
padding-bottom: 10px;
margin: 0;
}
.flexibleImage {
height: auto;
}
img.logo {
max-width: 100%;
max-height: 35px;
}
.properties-table {
width: 100%;
text-align: left;
font-size: 14px;
font-weight: 400;
font-family: Arial, sans-serif;
border-collapse: collapse;
}
.properties-table tr:first-child {
border-top: 1px solid rgba(196, 196, 196, 0.2);
}
.properties-table tr:first-child>td {
padding-top: 24px;
}
.properties-table tr:last-child {
border-bottom: 1px solid rgba(196, 196, 196, 0.2);
}
.properties-table tr:last-child>td {
padding-bottom: 24px;
}
.properties-table td {
line-height: 24px;
vertical-align: top;
padding: 4px 15px;
}
.td-right {
text-align: right;
white-space: nowrap;
}
.btn-primary {
text-decoration: none;
color: #FFF;
background-color: #348eda;
border: solid #348eda;
width: 100%;
line-height: 2em;
font-weight: bold;
text-align: center;
cursor: pointer;
display: inline-block;
text-transform: capitalize;
}
.btn-primary a {
color: #fff;
}
</style>
</head>
<body>
<div class="wrapper">
<center>
<div style="-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; table-layout: fixed; width: 100%; max-width: 448px; padding: 60px 20px; font-size: 14px;">
<table border="0" align="center" width="100%">
<tr>
<td></td>
<td class="container" width="600">
<div class="content">
<table class="main" width="100%" cellpadding="0" cellspacing="0" itemprop="action" itemscope itemtype="http://schema.org/ConfirmAction">
{% block content %}
{% endblock %}
</table>
<div class="footer">
<table width="100%">
<tr>
<td class="align-center content-block">Powered by <a href="https://goauthentik.io?utm_source=authentik&utm_medium=email">authentik</a>.</td>
</tr>
</table>
</div>
</div>
</td>
<td></td>
<td style="padding: 20px;border: 1px solid #c1c1c1;">
<table width="100%" style="background-color: #FFFFFF; border-spacing: 0; margin-top: 15px;">
<tr height="80">
<td align="center" style="padding: 20px 0;">
<img src="{% block logo_url %}cid:logo.png{% endblock %}" border="0=" alt="authentik logo" class="flexibleImage logo">
</td>
</tr>
{% block content %}
{% endblock %}
</table>
</td>
</tr>
</table>
</body>
<tr>
<td>
<table border="0" style="margin-top: 10px;" width="100%">
<tr>
<td style="background: #FAFBFB;">
<table style="width: 100%;">
{% block sub_content %}
{% endblock %}
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center">
Powered by <a href="https://goauthentik.io?utm_source=authentik&utm_medium=email">authentik</a>.
</td>
</tr>
</table>
</div>
</center>
</div>
</body>
</html>

View file

@ -0,0 +1,52 @@
{% extends "email/base.html" %}
{% load i18n %}
{% block content %}
<tr>
<td align="center">
<h1>
{{ title }}
</h1>
</td>
</tr>
<tr>
<td align="center">
<table border="0">
<tr>
<td align="center" style="max-width: 300px; padding: 20px 0; color: #212124;">
{{ body }}
</td>
</tr>
{% if key_value %}
<tr>
<td>
<table class="properties-table" width="100%">
<tbody>
{% for key, value in key_value.items %}
<tr>
<td class="td-right">{{ key }}</td>
<td class="td-left">{{ value }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</td>
</tr>
{% endif %}
</table>
</td>
</tr>
{% endblock %}
{% block sub_content %}
{% if source %}
<tr>
<td style="padding: 20px; font-size: 12px; color: #212124;" align="center">
{% blocktranslate with name=source.from %}
This email was sent from the notification transport <code>{{name}}</code>.
{% endblocktranslate %}
</td>
</tr>
{% endif %}
{% endblock %}

View file

@ -1,45 +0,0 @@
{% extends "email/base.html" %}
{% load i18n %}
{% block content %}
<tr>
<td class="alert alert-brand">
{{ title }}
</td>
</tr>
<tr>
<td class="content-wrap">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
{{ body }}
</td>
</tr>
{% if key_value %}
<tr>
<td class="content-block align-center">
<table class="body">
<tr>
<td>{% trans "Additional Information" %}</td>
</tr>
<tr>
<td>
<table class="body-items" cellpadding="0" cellspacing="0">
{% for key, value in key_value.items %}
<tr>
<td>{{ key }}</td>
<td class="align-right">{{ value }}</td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</td>
</tr>
{% endif %}
</table>
</td>
</tr>
{% endblock %}

View file

@ -5,49 +5,40 @@
{% block content %}
<tr>
<td class="alert alert-success">
{% blocktrans with username=user.username %}
Hi {{ username }},
{% endblocktrans %}
</td>
<td align="center">
<h1>
{% blocktrans with username=user.username %}
Hi {{ username }},
{% endblocktrans %}
</h1>
</td>
</tr>
<tr>
<td class="content-wrap">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
{% blocktrans %}
You recently requested to change your password for your authentik account. Use the button below to set a new password.
{% endblocktrans %}
</td>
</tr>
<tr>
<td class="content-block">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="center">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a id="confirm" href="{{ url }}" rel="noopener noreferrer" target="_blank">{% trans 'Reset Password' %}</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="content-block">
{% blocktrans with expires=expires|naturaltime %}
If you did not request a password change, please ignore this Email. The link above is valid for {{ expires }}.
{% endblocktrans %}
</td>
</tr>
</table>
</td>
<td align="center">
<table border="0">
<tr>
<td align="center" style="max-width: 300px; padding: 20px 0; color: #212124;">
{% blocktrans %}
You recently requested to change your password for your authentik account. Use the button below to set a new password.
{% endblocktrans %}
</td>
</tr>
<tr>
<td align="center" class="btn btn-primary">
<a id="confirm" href="{{ url }}" rel="noopener noreferrer" target="_blank">{% trans 'Reset Password' %}</a>
</td>
</tr>
</table>
</td>
</tr>
{% endblock %}
{% block sub_content %}
<tr>
<td style="padding: 20px; font-size: 12px; color: #212124;" align="center">
{% blocktrans with expires=expires|naturaltime %}
If you did not request a password change, please ignore this Email. The link above is valid for {{ expires }}.
{% endblocktrans %}
</td>
</tr>
{% endblock %}

View file

@ -1,9 +1,21 @@
"""email utils"""
from email.mime.image import MIMEImage
from functools import lru_cache
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.utils import translation
@lru_cache()
def logo_data():
"""Get logo as MIME Image for emails"""
with open("web/icons/icon_left_brand.png", "rb") as _logo_file:
logo = MIMEImage(_logo_file.read())
logo.add_header("Content-ID", "logo.png")
return logo
class TemplateEmailMessage(EmailMultiAlternatives):
"""Wrapper around EmailMultiAlternatives with integrated template rendering"""
@ -12,4 +24,6 @@ class TemplateEmailMessage(EmailMultiAlternatives):
html_content = render_to_string(template_name, template_context)
super().__init__(**kwargs)
self.content_subtype = "html"
self.mixed_subtype = "related"
self.attach(logo_data())
self.attach_alternative(html_content, "text/html")

View file

@ -73,12 +73,12 @@ class Invitation(SerializerModel, ExpiringModel):
@property
def serializer(self) -> Serializer:
from authentik.stages.consent.api import UserConsentSerializer
from authentik.stages.invitation.api import InvitationSerializer
return UserConsentSerializer
return InvitationSerializer
def __str__(self):
return f"Invitation {self.invite_uuid.hex} created by {self.created_by}"
return f"Invitation {str(self.invite_uuid)} created by {self.created_by}"
class Meta:
verbose_name = _("Invitation")

View file

@ -132,5 +132,5 @@ entries:
- identifiers:
target: !KeyOf flow
stage: !KeyOf default-enrollment-user-login
order: 40
order: 100
model: authentik_flows.flowstagebinding

11
go.mod
View file

@ -21,8 +21,8 @@ require (
github.com/jellydator/ttlcache/v3 v3.1.0
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
github.com/pires/go-proxyproto v0.7.0
github.com/prometheus/client_golang v1.16.0
github.com/redis/go-redis/v9 v9.2.0
github.com/prometheus/client_golang v1.17.0
github.com/redis/go-redis/v9 v9.2.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
@ -65,10 +65,9 @@ require (
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.mongodb.org/mongo-driver v1.11.3 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect

21
go.sum
View file

@ -279,22 +279,21 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac h1:jWKYCNlX4J5s8M0nHYkh7Y7c9gRVDEb3mq51j5J0F5M=
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/redis/go-redis/v9 v9.2.0 h1:zwMdX0A4eVzse46YN18QhuDiM4uf3JmkOB4VZrdt5uI=
github.com/redis/go-redis/v9 v9.2.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM=
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=

View file

@ -45,9 +45,11 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL)
rs.KeyPrefix(RedisKeyPrefix)
rs.Options(sessions.Options{
HttpOnly: strings.ToLower(externalHost.Scheme) == "https",
HttpOnly: true,
Secure: strings.ToLower(externalHost.Scheme) == "https",
Domain: *p.CookieDomain,
SameSite: http.SameSiteLaxMode,
MaxAge: maxAge,
})
a.log.Trace("using redis session backend")

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-15 09:51+0000\n"
"POT-Creation-Date: 2023-10-02 12:46+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -375,63 +375,63 @@ msgstr ""
msgid "Event user"
msgstr ""
#: authentik/events/models.py:484
#: authentik/events/models.py:491
msgid "Notification Transport"
msgstr ""
#: authentik/events/models.py:485
#: authentik/events/models.py:492
msgid "Notification Transports"
msgstr ""
#: authentik/events/models.py:491
#: authentik/events/models.py:498
msgid "Notice"
msgstr ""
#: authentik/events/models.py:492
#: authentik/events/models.py:499
msgid "Warning"
msgstr ""
#: authentik/events/models.py:493
#: authentik/events/models.py:500
msgid "Alert"
msgstr ""
#: authentik/events/models.py:518
#: authentik/events/models.py:525
msgid "Notification"
msgstr ""
#: authentik/events/models.py:519
#: authentik/events/models.py:526
msgid "Notifications"
msgstr ""
#: authentik/events/models.py:529
#: authentik/events/models.py:536
msgid ""
"Select which transports should be used to notify the user. If none are "
"selected, the notification will only be shown in the authentik UI."
msgstr ""
#: authentik/events/models.py:537
#: authentik/events/models.py:544
msgid "Controls which severity level the created notifications will have."
msgstr ""
#: authentik/events/models.py:542
#: authentik/events/models.py:549
msgid ""
"Define which group of users this notification should be sent and shown to. "
"If left empty, Notification won't ben sent."
msgstr ""
#: authentik/events/models.py:560
#: authentik/events/models.py:567
msgid "Notification Rule"
msgstr ""
#: authentik/events/models.py:561
#: authentik/events/models.py:568
msgid "Notification Rules"
msgstr ""
#: authentik/events/models.py:581
#: authentik/events/models.py:588
msgid "Webhook Mapping"
msgstr ""
#: authentik/events/models.py:582
#: authentik/events/models.py:589
msgid "Webhook Mappings"
msgstr ""
@ -2099,21 +2099,21 @@ msgstr ""
msgid "Email sent."
msgstr ""
#: authentik/stages/email/templates/email/account_confirmation.html:9
#: authentik/stages/email/templates/email/account_confirmation.html:10
msgid "Welcome!"
msgstr ""
#: authentik/stages/email/templates/email/account_confirmation.html:12
#: authentik/stages/email/templates/email/account_confirmation.html:19
msgid ""
"We're excited to have you get started. First, you need to confirm your "
"account. Just press the button below."
msgstr ""
#: authentik/stages/email/templates/email/account_confirmation.html:21
#: authentik/stages/email/templates/email/account_confirmation.html:24
msgid "Confirm Account"
msgstr ""
#: authentik/stages/email/templates/email/account_confirmation.html:30
#: authentik/stages/email/templates/email/account_confirmation.html:36
#, python-format
msgid ""
"\n"
@ -2122,43 +2122,42 @@ msgid ""
" "
msgstr ""
#: authentik/stages/email/templates/email/account_confirmation.html:35
msgid ""
"If you have any questions, just reply to this email—we're always happy to "
"help out."
msgstr ""
#: authentik/stages/email/templates/email/generic.html:24
msgid "Additional Information"
msgstr ""
#: authentik/stages/email/templates/email/password_reset.html:9
#: authentik/stages/email/templates/email/event_notification.html:46
#, python-format
msgid ""
"\n"
" Hi %(username)s,\n"
" "
" This email was sent from the notification transport <code>%(name)s</"
"code>.\n"
" "
msgstr ""
#: authentik/stages/email/templates/email/password_reset.html:19
#: authentik/stages/email/templates/email/password_reset.html:10
#, python-format
msgid ""
"\n"
" You recently requested to change your password for your "
"authentik account. Use the button below to set a new password.\n"
" "
" Hi %(username)s,\n"
" "
msgstr ""
#: authentik/stages/email/templates/email/password_reset.html:33
#: authentik/stages/email/templates/email/password_reset.html:21
msgid ""
"\n"
" You recently requested to change your password for your authentik "
"account. Use the button below to set a new password.\n"
" "
msgstr ""
#: authentik/stages/email/templates/email/password_reset.html:28
msgid "Reset Password"
msgstr ""
#: authentik/stages/email/templates/email/password_reset.html:45
#: authentik/stages/email/templates/email/password_reset.html:39
#, python-format
msgid ""
"\n"
" If you did not request a password change, please ignore "
"this Email. The link above is valid for %(expires)s.\n"
" "
" If you did not request a password change, please ignore this Email. The "
"link above is valid for %(expires)s.\n"
" "
msgstr ""
#: authentik/stages/email/templates/email/setup.html:9

42
poetry.lock generated
View file

@ -265,13 +265,13 @@ files = [
[[package]]
name = "astroid"
version = "2.15.7"
version = "2.15.8"
description = "An abstract syntax tree for Python with inference support."
optional = false
python-versions = ">=3.7.2"
files = [
{file = "astroid-2.15.7-py3-none-any.whl", hash = "sha256:958f280532e36ca84a13023f15cb1556fb6792d193acb87e1f3ca536b6fa6bd2"},
{file = "astroid-2.15.7.tar.gz", hash = "sha256:c522f2832a900e27a7d284b9b6ef670d2495f760ede3c8c0b004a5641d3c5987"},
{file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
{file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
]
[package.dependencies]
@ -1201,13 +1201,13 @@ prometheus-client = ">=0.7"
[[package]]
name = "django-redis"
version = "5.3.0"
version = "5.4.0"
description = "Full featured redis cache backend for Django."
optional = false
python-versions = ">=3.6"
files = [
{file = "django-redis-5.3.0.tar.gz", hash = "sha256:8bc5793ec06b28ea802aad85ec437e7646511d4e571e07ccad19cfed8b9ddd44"},
{file = "django_redis-5.3.0-py3-none-any.whl", hash = "sha256:2d8660d39f586c41c9907d5395693c477434141690fd7eca9d32376af00b0aac"},
{file = "django-redis-5.4.0.tar.gz", hash = "sha256:6a02abaa34b0fea8bf9b707d2c363ab6adc7409950b2db93602e6cb292818c42"},
{file = "django_redis-5.4.0-py3-none-any.whl", hash = "sha256:ebc88df7da810732e2af9987f7f426c96204bf89319df4c6da6ca9a2942edd5b"},
]
[package.dependencies]
@ -2439,13 +2439,13 @@ attrs = ">=19.2.0"
[[package]]
name = "packaging"
version = "23.1"
version = "23.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
]
[[package]]
@ -2692,13 +2692,13 @@ files = [
[[package]]
name = "pydantic"
version = "2.4.1"
version = "2.4.2"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic-2.4.1-py3-none-any.whl", hash = "sha256:2b2240c8d54bb8f84b88e061fac1bdfa1761c2859c367f9d3afe0ec2966deddc"},
{file = "pydantic-2.4.1.tar.gz", hash = "sha256:b172505886028e4356868d617d2d1a776d7af1625d1313450fd51bdd19d9d61f"},
{file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"},
{file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"},
]
[package.dependencies]
@ -2878,17 +2878,17 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
[[package]]
name = "pylint"
version = "2.17.6"
version = "2.17.7"
description = "python code static checker"
optional = false
python-versions = ">=3.7.2"
files = [
{file = "pylint-2.17.6-py3-none-any.whl", hash = "sha256:18a1412e873caf8ffb56b760ce1b5643675af23e6173a247b502406b24c716af"},
{file = "pylint-2.17.6.tar.gz", hash = "sha256:be928cce5c76bf9acdc65ad01447a1e0b1a7bccffc609fb7fc40f2513045bd05"},
{file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"},
{file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"},
]
[package.dependencies]
astroid = ">=2.15.7,<=2.17.0-dev0"
astroid = ">=2.15.8,<=2.17.0-dev0"
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""}
isort = ">=4.2.5,<6"
@ -4069,19 +4069,19 @@ files = [
[[package]]
name = "webauthn"
version = "1.10.1"
version = "1.11.0"
description = "Pythonic WebAuthn"
optional = false
python-versions = "*"
files = [
{file = "webauthn-1.10.1-py3-none-any.whl", hash = "sha256:1d6b2c0753344df4c067a478f0e7f0e6cbb561f3d40342472f421657cdd16d41"},
{file = "webauthn-1.10.1.tar.gz", hash = "sha256:94fc8265cccce88e1e43dc2008f3d8bb1f05fdd547246efa1be8ef684a6c3a7b"},
{file = "webauthn-1.11.0-py3-none-any.whl", hash = "sha256:9c8a81f7e310aee022a038ae2c76711bcf0a94521a471225e05c36871f83eeda"},
{file = "webauthn-1.11.0.tar.gz", hash = "sha256:1e808de1e3625a4b361e249e1bbb254d2a3a5c6b206e6f7260c4febe51f45276"},
]
[package.dependencies]
asn1crypto = ">=1.4.0"
cbor2 = ">=5.4.2.post1"
cryptography = ">=41.0.1"
cbor2 = ">=5.4.6"
cryptography = ">=41.0.4"
pydantic = ">=1.10.11"
pyOpenSSL = ">=23.2.0"

View file

@ -4,7 +4,7 @@
"targetLocales": [
"en",
"pseudo-LOCALE",
"fr_FR",
"fr",
"tr",
"es",
"pl",

40
web/package-lock.json generated
View file

@ -32,11 +32,11 @@
"chartjs-adapter-moment": "^1.0.1",
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.32.2",
"core-js": "^3.33.0",
"country-flag-icons": "^1.5.7",
"fuse.js": "^6.6.2",
"lit": "^2.8.0",
"mermaid": "^10.4.0",
"mermaid": "^10.5.0",
"rapidoc": "^9.3.4",
"style-mod": "^4.1.0",
"webcomponent-qr-code": "^1.2.0",
@ -87,7 +87,7 @@
"pyright": "^1.1.329",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rollup": "^3.29.3",
"rollup": "^3.29.4",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-cssimport": "^1.0.3",
"rollup-plugin-postcss-lit": "^2.1.0",
@ -100,9 +100,9 @@
"vite-tsconfig-paths": "^4.2.1"
},
"optionalDependencies": {
"@esbuild/darwin-arm64": "^0.19.3",
"@esbuild/darwin-arm64": "^0.19.4",
"@esbuild/linux-amd64": "^0.18.11",
"@esbuild/linux-arm64": "^0.19.3"
"@esbuild/linux-arm64": "^0.19.4"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@ -2402,9 +2402,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.19.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.3.tgz",
"integrity": "sha512-kw7e3FXU+VsJSSSl2nMKvACYlwtvZB8RUIeVShIEY6PVnuZ3c9+L9lWB2nWeeKWNNYDdtL19foCQ0ZyUL7nqGw==",
"version": "0.19.4",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.4.tgz",
"integrity": "sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==",
"cpu": [
"arm64"
],
@ -2481,9 +2481,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.19.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.3.tgz",
"integrity": "sha512-qXvYKmXj8GcJgWq3aGvxL/JG1ZM3UR272SdPU4QSTzD0eymrM7leiZH77pvY3UetCy0k1xuXZ+VPvoJNdtrsWQ==",
"version": "0.19.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.4.tgz",
"integrity": "sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==",
"cpu": [
"arm64"
],
@ -12095,9 +12095,9 @@
}
},
"node_modules/core-js": {
"version": "3.32.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz",
"integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==",
"version": "3.33.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.0.tgz",
"integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@ -17181,9 +17181,9 @@
}
},
"node_modules/mermaid": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.4.0.tgz",
"integrity": "sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw==",
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.5.0.tgz",
"integrity": "sha512-9l0o1uUod78D3/FVYPGSsgV+Z0tSnzLBDiC9rVzvelPxuO80HbN1oDr9ofpPETQy9XpypPQa26fr09VzEPfvWA==",
"dependencies": {
"@braintree/sanitize-url": "^6.0.1",
"@types/d3-scale": "^4.0.3",
@ -20023,9 +20023,9 @@
"integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="
},
"node_modules/rollup": {
"version": "3.29.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.3.tgz",
"integrity": "sha512-T7du6Hum8jOkSWetjRgbwpM6Sy0nECYrYRSmZjayFcOddtKJWU4d17AC3HNUk7HRuqy4p+G7aEZclSHytqUmEg==",
"version": "3.29.4",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
"integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"

View file

@ -50,11 +50,11 @@
"chartjs-adapter-moment": "^1.0.1",
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.32.2",
"core-js": "^3.33.0",
"country-flag-icons": "^1.5.7",
"fuse.js": "^6.6.2",
"lit": "^2.8.0",
"mermaid": "^10.4.0",
"mermaid": "^10.5.0",
"rapidoc": "^9.3.4",
"style-mod": "^4.1.0",
"webcomponent-qr-code": "^1.2.0",
@ -105,7 +105,7 @@
"pyright": "^1.1.329",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rollup": "^3.29.3",
"rollup": "^3.29.4",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-cssimport": "^1.0.3",
"rollup-plugin-postcss-lit": "^2.1.0",
@ -118,8 +118,8 @@
"vite-tsconfig-paths": "^4.2.1"
},
"optionalDependencies": {
"@esbuild/darwin-arm64": "^0.19.3",
"@esbuild/darwin-arm64": "^0.19.4",
"@esbuild/linux-amd64": "^0.18.11",
"@esbuild/linux-arm64": "^0.19.3"
"@esbuild/linux-arm64": "^0.19.4"
}
}

View file

@ -73,7 +73,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
row(item: FlowStageBinding): TemplateResult[] {
return [
html`${item.order}`,
html`<pre>${item.order}</pre>`,
html`${item.stageObj?.name}`,
html`${item.stageObj?.verboseName}`,
html` <ak-forms-modal>

View file

@ -145,7 +145,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
row(item: PolicyBinding): TemplateResult[] {
return [
html`${item.order}`,
html`<pre>${item.order}</pre>`,
html`${this.getPolicyUserGroupRow(item)}`,
html` <ak-label color=${item.enabled ? PFColor.Green : PFColor.Orange}>
${item.enabled ? msg("Yes") : msg("No")}

View file

@ -62,7 +62,7 @@ export class InvitationStageForm extends ModelForm<InvitationStage, string> {
type="checkbox"
?checked=${first(
this.instance?.continueFlowWithoutInvitation,
true,
false,
)}
/>
<span class="pf-c-switch__toggle">

View file

@ -29,7 +29,7 @@ export class AKLocaleSensitiveDemoComponent extends LitElement {
export const InFrench = () =>
html`<div style="background: #fff; padding: 4em">
<ak-locale-context locale="fr_FR"
<ak-locale-context locale="fr"
><ak-locale-demo-component
>Everything is not ok.</ak-locale-demo-component
></ak-locale-context
@ -39,12 +39,12 @@ export const InFrench = () =>
export const SwitchingBackAndForth = () => {
let lang = "en";
window.setInterval(() => {
lang = lang === "en" ? "fr_FR" : "en";
lang = lang === "en" ? "fr" : "en";
window.dispatchEvent(customEvent(EVENT_LOCALE_REQUEST, { locale: lang }));
}, 1000);
return html`<div style="background: #fff; padding: 4em">
<ak-locale-context locale="fr_FR">
<ak-locale-context locale="fr">
<ak-locale-sensitive-demo-component></ak-locale-sensitive-demo-component
></ak-locale-context>
</div>`;

View file

@ -24,9 +24,6 @@ export { enLocale };
// language uses both "regional" and "script" suffixes. The regexes use the language and any region
// or script.
//
// French is currently an oddity; the translator provided the France regional version explicitly,
// and we fall back to that regardless of region. Sorry, Québécois.
//
// Chinese locales usually (but not always) use the script rather than region suffix. The default
// (optional) fallback for Chinese (zh) is "Chinese (simplified)", which is why it has that odd
// regex syntax at the end which means "match zh as long as it's not followed by a [:word:] token";
@ -43,7 +40,7 @@ const LOCALE_TABLE: LocaleRow[] = [
["en", /^en([_-]|$)/i, () => msg("English"), async () => await import("@goauthentik/locales/en")],
["es", /^es([_-]|$)/i, () => msg("Spanish"), async () => await import("@goauthentik/locales/es")],
["de", /^de([_-]|$)/i, () => msg("German"), async () => await import("@goauthentik/locales/de")],
["fr_FR", /^fr([_-]|$)/i, () => msg("French"), async () => await import("@goauthentik/locales/fr_FR")],
["fr", /^fr([_-]|$)/i, () => msg("French"), async () => await import("@goauthentik/locales/fr")],
["pl", /^pl([_-]|$)/i, () => msg("Polish"), async () => await import("@goauthentik/locales/pl")],
["tr", /^tr([_-]|$)/i, () => msg("Turkish"), async () => await import("@goauthentik/locales/tr")],
["zh-Hant", /^zh[_-](HK|Hant)/i, () => msg("Chinese (traditional)"), async () => await import("@goauthentik/locales/zh-Hant")],

View file

@ -14,7 +14,7 @@ export const targetLocales = [
`de`,
`en`,
`es`,
`fr_FR`,
`fr`,
`pl`,
`pseudo-LOCALE`,
`tr`,
@ -31,7 +31,7 @@ export const allLocales = [
`en`,
`en`,
`es`,
`fr_FR`,
`fr`,
`pl`,
`pseudo-LOCALE`,
`tr`,

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="zh-Hans" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -613,9 +613,9 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>未找到 URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot;。</target>
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>未找到 URL "
<x id="0" equiv-text="${this.url}"/>"。</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1067,8 +1067,8 @@
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 &quot;.*&quot;。请注意这可能带来的安全影响。</target>
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1814,8 +1814,8 @@
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 &quot;fa-test&quot;。</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -3238,8 +3238,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 &quot;memberUid&quot; 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -4031,8 +4031,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 &quot;minutes=5&quot;。</target>
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -4041,8 +4041,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</source>
<target>格式:&quot;weeks=3;days=2;hours=3,seconds=2&quot;。</target>
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>格式:"weeks=3;days=2;hours=3,seconds=2"。</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
@ -4238,10 +4238,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>您确定要更新
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot; 吗?</target>
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -5342,7 +5342,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<source>A "roaming" authenticator, like a YubiKey</source>
<target>像 YubiKey 这样的“漫游”身份验证器</target>
</trans-unit>
@ -5677,10 +5677,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>&quot;
<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;,类型为
<x id="0" equiv-text="${prompt.name}"/>"
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
<x id="2" equiv-text="${prompt.type}"/></target>
</trans-unit>
@ -5729,7 +5729,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>如果设置时长大于 0用户可以选择“保持登录”选项这将使用户的会话延长此处设置的时间。</target>
</trans-unit>

View file

@ -24,6 +24,10 @@ This ingress handles authentication requests, and the sign-in flow.
Add these annotations to the ingress you want to protect
:::warning
This configuration requires that you enable [`allow-snippet-annotations`](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#allow-snippet-annotations), for example by setting `controller.allowSnippetAnnotations` to `true` in your helm values for the ingress-nginx installation.
:::
```yaml
metadata:
annotations:

View file

@ -15,14 +15,14 @@
"@mdx-js/react": "^1.6.22",
"clsx": "^2.0.0",
"disqus-react": "^1.1.5",
"postcss": "^8.4.30",
"postcss": "^8.4.31",
"rapidoc": "^9.3.4",
"react": "^17.0.2",
"react-before-after-slider-component": "^1.1.8",
"react-dom": "^17.0.2",
"react-feather": "^2.0.10",
"react-toggle": "^4.1.3",
"react-tooltip": "^5.21.4",
"react-tooltip": "^5.21.5",
"remark-github": "^12.0.0"
},
"devDependencies": {
@ -9439,9 +9439,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.30",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
"integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"funding": [
{
"type": "opencollective",
@ -10624,9 +10624,9 @@
}
},
"node_modules/react-tooltip": {
"version": "5.21.4",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.4.tgz",
"integrity": "sha512-LZsllEbiu63zNwuCalq3gIFcBu2Xf0I0fMg7uuF7/5ROo5//uHe8Sum7v9L1Rtp6IozcoU9YAjkNUZdrxutsNg==",
"version": "5.21.5",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.5.tgz",
"integrity": "sha512-ey70qf6pBGi4U6xpyNlZAHobAhlo2dfxmImR2Bzd/DbLTsAYWz3TEaK+RMFuUZMq6hSPRbUHQSkP2rHBq4uFVg==",
"dependencies": {
"@floating-ui/dom": "^1.0.0",
"classnames": "^2.3.0"
@ -20667,9 +20667,9 @@
}
},
"postcss": {
"version": "8.4.30",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
"integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"requires": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
@ -21449,9 +21449,9 @@
}
},
"react-tooltip": {
"version": "5.21.4",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.4.tgz",
"integrity": "sha512-LZsllEbiu63zNwuCalq3gIFcBu2Xf0I0fMg7uuF7/5ROo5//uHe8Sum7v9L1Rtp6IozcoU9YAjkNUZdrxutsNg==",
"version": "5.21.5",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.5.tgz",
"integrity": "sha512-ey70qf6pBGi4U6xpyNlZAHobAhlo2dfxmImR2Bzd/DbLTsAYWz3TEaK+RMFuUZMq6hSPRbUHQSkP2rHBq4uFVg==",
"requires": {
"@floating-ui/dom": "^1.0.0",
"classnames": "^2.3.0"

View file

@ -22,14 +22,14 @@
"@mdx-js/react": "^1.6.22",
"clsx": "^2.0.0",
"disqus-react": "^1.1.5",
"postcss": "^8.4.30",
"postcss": "^8.4.31",
"rapidoc": "^9.3.4",
"react": "^17.0.2",
"react-before-after-slider-component": "^1.1.8",
"react-dom": "^17.0.2",
"react-feather": "^2.0.10",
"react-toggle": "^4.1.3",
"react-tooltip": "^5.21.4",
"react-tooltip": "^5.21.5",
"remark-github": "^12.0.0"
},
"browserslist": {