diff --git a/authentik/core/migrations/0030_user_type.py b/authentik/core/migrations/0030_user_type.py index 93a7a8884..1e4884c72 100644 --- a/authentik/core/migrations/0030_user_type.py +++ b/authentik/core/migrations/0030_user_type.py @@ -12,7 +12,7 @@ def migrate_user_type(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): from authentik.core.models import UserTypes for user in User.objects.using(db_alias).all(): - user.type = UserTypes.DEFAULT + user.type = UserTypes.INTERNAL if "goauthentik.io/user/service-account" in user.attributes: user.type = UserTypes.SERVICE_ACCOUNT if "goauthentik.io/user/override-ips" in user.attributes: diff --git a/authentik/core/migrations/0031_alter_user_type.py b/authentik/core/migrations/0031_alter_user_type.py new file mode 100644 index 000000000..9140a4e39 --- /dev/null +++ b/authentik/core/migrations/0031_alter_user_type.py @@ -0,0 +1,40 @@ +# Generated by Django 4.1.10 on 2023-07-21 12:54 + +from django.apps.registry import Apps +from django.db import migrations, models +from django.db.backends.base.schema import BaseDatabaseSchemaEditor + + +def migrate_user_type_v2(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): + db_alias = schema_editor.connection.alias + User = apps.get_model("authentik_core", "User") + + from authentik.core.models import UserTypes + + for user in User.objects.using(db_alias).all(): + if user.type != "default": + continue + user.type = UserTypes.INTERNAL + user.save() + +class Migration(migrations.Migration): + dependencies = [ + ("authentik_core", "0030_user_type"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="type", + field=models.TextField( + choices=[ + ("internal", "Internal"), + ("external", "External"), + ("service_account", "Service Account"), + ("internal_service_account", "Internal Service Account"), + ], + default="internal", + ), + ), + migrations.RunPython(migrate_user_type_v2), + ] diff --git a/authentik/core/models.py b/authentik/core/models.py index 719d4e66f..72ede3d43 100644 --- a/authentik/core/models.py +++ b/authentik/core/models.py @@ -67,7 +67,7 @@ class UserTypes(models.TextChoices): """User types, both for grouping, licensing and permissions in the case of the internal_service_account""" - DEFAULT = "default" + INTERNAL = "internal" EXTERNAL = "external" # User-created service accounts @@ -161,7 +161,7 @@ class User(SerializerModel, GuardianUserMixin, AbstractUser): uuid = models.UUIDField(default=uuid4, editable=False, unique=True) name = models.TextField(help_text=_("User's display name.")) path = models.TextField(default="users") - type = models.TextField(choices=UserTypes.choices, default=UserTypes.DEFAULT) + type = models.TextField(choices=UserTypes.choices, default=UserTypes.INTERNAL) sources = models.ManyToManyField("Source", through="UserSourceConnection") ak_groups = models.ManyToManyField("Group", related_name="users") diff --git a/authentik/enterprise/api.py b/authentik/enterprise/api.py index 2f29832a2..cdc63563c 100644 --- a/authentik/enterprise/api.py +++ b/authentik/enterprise/api.py @@ -137,7 +137,7 @@ class LicenseViewSet(UsedByMixin, ModelViewSet): last_month = now() - timedelta(days=30) # Forecast for default users users_in_last_month = User.objects.filter( - type=UserTypes.DEFAULT, date_joined__gte=last_month + type=UserTypes.INTERNAL, date_joined__gte=last_month ).count() # Forecast for external users external_in_last_month = LicenseKey.get_external_user_count() diff --git a/authentik/enterprise/models.py b/authentik/enterprise/models.py index 1abf30da3..da36738de 100644 --- a/authentik/enterprise/models.py +++ b/authentik/enterprise/models.py @@ -105,7 +105,7 @@ class LicenseKey: @staticmethod def get_default_user_count(): """Get current default user count""" - return LicenseKey.base_user_qs().filter(type=UserTypes.DEFAULT).count() + return LicenseKey.base_user_qs().filter(type=UserTypes.INTERNAL).count() @staticmethod def get_external_user_count(): diff --git a/authentik/enterprise/policy.py b/authentik/enterprise/policy.py index c736bd59e..710222816 100644 --- a/authentik/enterprise/policy.py +++ b/authentik/enterprise/policy.py @@ -24,7 +24,7 @@ class EnterprisePolicy(Policy): def passes(self, request: PolicyRequest) -> PolicyResult: if not LicenseKey.get_total().is_valid(): return PolicyResult(False) - if request.user.type != UserTypes.DEFAULT: + if request.user.type != UserTypes.INTERNAL: return PolicyResult(False) return PolicyResult(True) diff --git a/blueprints/schema.json b/blueprints/schema.json index 7747f8ac4..40b7984ab 100644 --- a/blueprints/schema.json +++ b/blueprints/schema.json @@ -3984,7 +3984,7 @@ "type": { "type": "string", "enum": [ - "default", + "internal", "external", "service_account", "internal_service_account" @@ -4185,7 +4185,7 @@ "type": { "type": "string", "enum": [ - "default", + "internal", "external", "service_account", "internal_service_account" @@ -4390,7 +4390,7 @@ "type": { "type": "string", "enum": [ - "default", + "internal", "external", "service_account", "internal_service_account" @@ -6556,7 +6556,7 @@ "type": { "type": "string", "enum": [ - "default", + "internal", "external", "service_account", "internal_service_account" @@ -7301,7 +7301,7 @@ "type": { "type": "string", "enum": [ - "default", + "internal", "external", "service_account", "internal_service_account" @@ -8387,7 +8387,7 @@ "type": { "type": "string", "enum": [ - "default", + "internal", "external", "service_account", "internal_service_account" diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index 08d1ad17c..1f3fe8b5b 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-16 13:59+0000\n" +"POT-Creation-Date: 2023-07-21 13:04+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -2017,33 +2017,33 @@ msgstr "" msgid "Dummy Stages" msgstr "" -#: authentik/stages/email/models.py:25 +#: authentik/stages/email/models.py:26 msgid "Password Reset" msgstr "" -#: authentik/stages/email/models.py:29 +#: authentik/stages/email/models.py:30 msgid "Account Confirmation" msgstr "" -#: authentik/stages/email/models.py:58 +#: authentik/stages/email/models.py:59 msgid "" "When enabled, global Email connection settings will be used and connection " "settings below will be ignored." msgstr "" -#: authentik/stages/email/models.py:73 +#: authentik/stages/email/models.py:74 msgid "Activate users upon completion of stage." msgstr "" -#: authentik/stages/email/models.py:77 +#: authentik/stages/email/models.py:78 msgid "Time in minutes the token sent is valid." msgstr "" -#: authentik/stages/email/models.py:122 +#: authentik/stages/email/models.py:132 msgid "Email Stage" msgstr "" -#: authentik/stages/email/models.py:123 +#: authentik/stages/email/models.py:133 msgid "Email Stages" msgstr "" diff --git a/schema.yml b/schema.yml index 15f06c636..3af1a2e42 100644 --- a/schema.yml +++ b/schema.yml @@ -4609,12 +4609,12 @@ paths: schema: type: string enum: - - default - external + - internal - internal_service_account - service_account description: |- - * `default` - Default + * `internal` - Internal * `external` - External * `service_account` - Service Account * `internal_service_account` - Internal Service Account @@ -42581,13 +42581,13 @@ components: - user UserTypeEnum: enum: - - default + - internal - external - service_account - internal_service_account type: string description: |- - * `default` - Default + * `internal` - Internal * `external` - External * `service_account` - Service Account * `internal_service_account` - Internal Service Account diff --git a/web/src/admin/enterprise/EnterpriseLicenseListPage.ts b/web/src/admin/enterprise/EnterpriseLicenseListPage.ts index 6e7227ef6..8082a10e6 100644 --- a/web/src/admin/enterprise/EnterpriseLicenseListPage.ts +++ b/web/src/admin/enterprise/EnterpriseLicenseListPage.ts @@ -92,6 +92,24 @@ export class EnterpriseLicenseListPage extends TablePage { ]; } + // TODO: Make this more generic, maybe automatically get the plural name + // of the object to use in the renderEmpty + renderEmpty(inner?: TemplateResult): TemplateResult { + return super.renderEmpty(html` + ${inner + ? inner + : html` +
+ ${this.searchEnabled() ? this.renderEmptyClearSearch() : html``} +
+
${this.renderObjectCreate()}
+
`} + `); + } + renderToolbarSelected(): TemplateResult { const disabled = this.selectedElements.length < 1; return html` { ~ ${(this.forecast?.users || 0) + diff --git a/web/src/admin/users/UserForm.ts b/web/src/admin/users/UserForm.ts index 55dc52f58..c46b205c1 100644 --- a/web/src/admin/users/UserForm.ts +++ b/web/src/admin/users/UserForm.ts @@ -80,22 +80,27 @@ export class UserForm extends ModelForm { Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5825,6 +5798,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/en.xlf b/web/xliff/en.xlf index 913b11bed..558bcb539 100644 --- a/web/xliff/en.xlf +++ b/web/xliff/en.xlf @@ -6091,45 +6091,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -6141,6 +6114,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/es.xlf b/web/xliff/es.xlf index 924719034..66943b48c 100644 --- a/web/xliff/es.xlf +++ b/web/xliff/es.xlf @@ -5683,45 +5683,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5733,6 +5706,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/fr_FR.xlf b/web/xliff/fr_FR.xlf index 4089c3054..e92b47ee2 100644 --- a/web/xliff/fr_FR.xlf +++ b/web/xliff/fr_FR.xlf @@ -5790,45 +5790,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5840,6 +5813,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/pl.xlf b/web/xliff/pl.xlf index 501b84c43..7c53d39e8 100644 --- a/web/xliff/pl.xlf +++ b/web/xliff/pl.xlf @@ -5922,45 +5922,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5972,6 +5945,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/pseudo-LOCALE.xlf b/web/xliff/pseudo-LOCALE.xlf index ac4e90231..1f75bd37c 100644 --- a/web/xliff/pseudo-LOCALE.xlf +++ b/web/xliff/pseudo-LOCALE.xlf @@ -6026,45 +6026,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -6076,6 +6049,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/tr.xlf b/web/xliff/tr.xlf index 2f7a31388..d2d47721e 100644 --- a/web/xliff/tr.xlf +++ b/web/xliff/tr.xlf @@ -5673,45 +5673,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5723,6 +5696,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/zh-Hans.xlf b/web/xliff/zh-Hans.xlf index 4f7b4e8ab..a9a78da07 100644 --- a/web/xliff/zh-Hans.xlf +++ b/web/xliff/zh-Hans.xlf @@ -1,4 +1,4 @@ - + @@ -618,9 +618,9 @@ - The URL "" was not found. - 未找到 URL " - "。 + The URL "" was not found. + 未找到 URL " + "。 @@ -1072,8 +1072,8 @@ - To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have. - 要允许任何重定向 URI,请将此值设置为 ".*"。请注意这可能带来的安全影响。 + To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have. + 要允许任何重定向 URI,请将此值设置为 ".*"。请注意这可能带来的安全影响。 @@ -1819,8 +1819,8 @@ - Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test". - 输入完整 URL、相对路径,或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。 + Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test". + 输入完整 URL、相对路径,或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。 @@ -3248,8 +3248,8 @@ doesn't pass when either or both of the selected options are equal or above the - 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,...' - 包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...' + 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,...' + 包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...' @@ -4046,8 +4046,8 @@ doesn't pass when either or both of the selected options are equal or above the - When using an external logging solution for archiving, this can be set to "minutes=5". - 使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。 + When using an external logging solution for archiving, this can be set to "minutes=5". + 使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。 @@ -4056,8 +4056,8 @@ doesn't pass when either or both of the selected options are equal or above the - Format: "weeks=3;days=2;hours=3,seconds=2". - 格式:"weeks=3;days=2;hours=3,seconds=2"。 + Format: "weeks=3;days=2;hours=3,seconds=2". + 格式:"weeks=3;days=2;hours=3,seconds=2"。 @@ -4253,10 +4253,10 @@ doesn't pass when either or both of the selected options are equal or above the - Are you sure you want to update ""? + Are you sure you want to update ""? 您确定要更新 - " - " 吗? + " + " 吗? @@ -5372,7 +5372,7 @@ doesn't pass when either or both of the selected options are equal or above the - A "roaming" authenticator, like a YubiKey + A "roaming" authenticator, like a YubiKey 像 YubiKey 这样的“漫游”身份验证器 @@ -5712,10 +5712,10 @@ doesn't pass when either or both of the selected options are equal or above the - ("", of type ) + ("", of type ) - (" - ",类型为 + (" + ",类型为 @@ -5764,7 +5764,7 @@ doesn't pass when either or both of the selected options are equal or above the - 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. + 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. 如果设置时长大于 0,用户可以选择“保持登录”选项,这将使用户的会话延长此处设置的时间。 @@ -7617,10 +7617,6 @@ Bindings to groups/users are checked against the user of the event. Licenses 许可证 - - TODO Copy - 未定副本 - License(s) 许可证 @@ -7629,34 +7625,6 @@ Bindings to groups/users are checked against the user of the event. Enterprise is in preview. 企业版目前处于预览状态。 - - How to get a license - 如何获取许可证 - - - Copy the installation ID - 复制安装 ID - - - Then open the customer portal - 然后打开消费者中心 - - - Forecasted default users - 预测默认用户 - - - Estimated user count one year from now - 预计从此时开始一年内的用户数 - - - Forecasted external users - 预测外部用户 - - - Estimated external user count one year from now - 预计从此时开始一年内的外部用户数 - Cumulative license expiry 累计许可证过期时间 @@ -7665,10 +7633,6 @@ Bindings to groups/users are checked against the user of the event. Update License 更新许可证 - - Create License - 创建许可证 - Warning: The current user count has exceeded the configured licenses. 警告:当前用户数超过了配置的许可证限制 @@ -7684,7 +7648,37 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses 管理企业版许可证 + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License - \ No newline at end of file + diff --git a/web/xliff/zh-Hant.xlf b/web/xliff/zh-Hant.xlf index 387bf36fd..6c12ad6ed 100644 --- a/web/xliff/zh-Hant.xlf +++ b/web/xliff/zh-Hant.xlf @@ -5728,45 +5728,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5778,6 +5751,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/web/xliff/zh_TW.xlf b/web/xliff/zh_TW.xlf index 577397538..70ec3208d 100644 --- a/web/xliff/zh_TW.xlf +++ b/web/xliff/zh_TW.xlf @@ -5727,45 +5727,18 @@ Bindings to groups/users are checked against the user of the event. Licenses - - TODO Copy - License(s) Enterprise is in preview. - - How to get a license - - - Copy the installation ID - - - Then open the customer portal - - - Forecasted default users - - - Estimated user count one year from now - - - Forecasted external users - - - Estimated external user count one year from now - Cumulative license expiry Update License - - Create License - Warning: The current user count has exceeded the configured licenses. @@ -5777,6 +5750,36 @@ Bindings to groups/users are checked against the user of the event. Manage enterprise licenses + + + No licenses found. + + + Send us feedback! + + + Get a license + + + Go to Customer Portal + + + Forecast internal users + + + Estimated user count one year from now based on current internal users and forecasted internal users. + + + Forecast external users + + + Estimated user count one year from now based on current external users and forecasted external users. + + + Install + + + Install License diff --git a/website/src/pages/pricing/index.jsx b/website/src/pages/pricing/index.jsx index 553e21a58..819849cf1 100644 --- a/website/src/pages/pricing/index.jsx +++ b/website/src/pages/pricing/index.jsx @@ -57,7 +57,7 @@ export default function pricingPage() {

- $5 /default user/month + $5 /internal user/month

$0.02{" "} @@ -129,8 +129,8 @@ export default function pricingPage() { body="We only offer support as part of an enterprise license. You can get community support on GitHub and Discord for the open-source version." />