Merge branch 'main' into dev

* main:
  web: bump API Client version (#9021)
  sources/ldap: add ability to disable password write on login (#8377)
  web: bump API Client version (#9020)
  lifecycle: migrate: ensure template schema exists before migrating (#8952)
  website/integrations: Update nextcloud Admin Group Expression (#7314)
  web/flow: general ux improvements (#8558)
  website: bump @types/react from 18.2.67 to 18.2.69 in /website (#9016)
  core: bump requests-oauthlib from 1.4.0 to 2.0.0 (#9018)
  web: bump the sentry group in /web with 2 updates (#9017)
  web/admin: small fixes (#9002)
  website: bump webpack-dev-middleware from 5.3.3 to 5.3.4 in /website (#9001)
  core: bump ruff from 0.3.3 to 0.3.4 (#8998)
  website/docs: Upgrade nginx reverse porxy config (#8947)
  website/docs: improve flow inspector docs (#8993)
  website/deverlop-docs website/integrations: add links to integrations template (#8995)
This commit is contained in:
Ken Sternberg
2024-03-25 07:44:17 -07:00
30 changed files with 358 additions and 144 deletions

View File

@ -53,6 +53,7 @@ class TestFlowInspector(APITestCase):
"title": flow.title, "title": flow.title,
"layout": "stacked", "layout": "stacked",
}, },
"flow_designation": "authentication",
"type": ChallengeTypes.NATIVE.value, "type": ChallengeTypes.NATIVE.value,
"password_fields": False, "password_fields": False,
"primary_action": "Log in", "primary_action": "Log in",

View File

@ -77,6 +77,7 @@ class LDAPSourceSerializer(SourceSerializer):
"group_object_filter", "group_object_filter",
"group_membership_field", "group_membership_field",
"object_uniqueness_field", "object_uniqueness_field",
"password_login_update_internal_password",
"sync_users", "sync_users",
"sync_users_password", "sync_users_password",
"sync_groups", "sync_groups",
@ -118,6 +119,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
"group_object_filter", "group_object_filter",
"group_membership_field", "group_membership_field",
"object_uniqueness_field", "object_uniqueness_field",
"password_login_update_internal_password",
"sync_users", "sync_users",
"sync_users_password", "sync_users_password",
"sync_groups", "sync_groups",

View File

@ -41,10 +41,11 @@ class LDAPBackend(InbuiltBackend):
# or has a password, but couldn't be authenticated by ModelBackend. # or has a password, but couldn't be authenticated by ModelBackend.
# This means we check with a bind to see if the LDAP password has changed # This means we check with a bind to see if the LDAP password has changed
if self.auth_user_by_bind(source, user, password): if self.auth_user_by_bind(source, user, password):
# Password given successfully binds to LDAP, so we save it in our Database if source.password_login_update_internal_password:
LOGGER.debug("Updating user's password in DB", user=user) # Password given successfully binds to LDAP, so we save it in our Database
user.set_password(password, signal=False) LOGGER.debug("Updating user's password in DB", user=user)
user.save() user.set_password(password, signal=False)
user.save()
return user return user
# Password doesn't match # Password doesn't match
LOGGER.debug("Failed to bind, password invalid") LOGGER.debug("Failed to bind, password invalid")

View File

@ -0,0 +1,29 @@
# Generated by Django 5.0.1 on 2024-01-31 18:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_ldap", "0003_ldapsource_client_certificate_ldapsource_sni_and_more"),
]
operations = [
migrations.AddField(
model_name="ldapsource",
name="password_login_update_internal_password",
field=models.BooleanField(
default=True,
help_text="Update internal authentik password when login succeeds with LDAP",
),
),
migrations.AlterField(
model_name="ldapsource",
name="password_login_update_internal_password",
field=models.BooleanField(
default=False,
help_text="Update internal authentik password when login succeeds with LDAP",
),
),
]

View File

@ -98,6 +98,11 @@ class LDAPSource(Source):
help_text=_("Property mappings used for group creation/updating."), help_text=_("Property mappings used for group creation/updating."),
) )
password_login_update_internal_password = models.BooleanField(
default=False,
help_text=_("Update internal authentik password when login succeeds with LDAP"),
)
sync_users = models.BooleanField(default=True) sync_users = models.BooleanField(default=True)
sync_users_password = models.BooleanField( sync_users_password = models.BooleanField(
default=True, default=True,

View File

@ -120,7 +120,9 @@ def validate_challenge_code(code: str, stage_view: StageView, user: User) -> Dev
stage=stage_view.executor.current_stage, stage=stage_view.executor.current_stage,
device_class=DeviceClasses.TOTP.value, device_class=DeviceClasses.TOTP.value,
) )
raise ValidationError(_("Invalid Token")) raise ValidationError(
_("Invalid Token. Please ensure the time on your device is accurate and try again.")
)
return device return device

View File

@ -10,7 +10,7 @@ from django.db.models import Q
from django.http import HttpResponse from django.http import HttpResponse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from drf_spectacular.utils import PolymorphicProxySerializer, extend_schema_field from drf_spectacular.utils import PolymorphicProxySerializer, extend_schema_field
from rest_framework.fields import BooleanField, CharField, DictField, ListField from rest_framework.fields import BooleanField, CharField, ChoiceField, DictField, ListField
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from sentry_sdk.hub import Hub from sentry_sdk.hub import Hub
@ -66,6 +66,7 @@ class IdentificationChallenge(Challenge):
user_fields = ListField(child=CharField(), allow_empty=True, allow_null=True) user_fields = ListField(child=CharField(), allow_empty=True, allow_null=True)
password_fields = BooleanField() password_fields = BooleanField()
application_pre = CharField(required=False) application_pre = CharField(required=False)
flow_designation = ChoiceField(FlowDesignation.choices)
enroll_url = CharField(required=False) enroll_url = CharField(required=False)
recovery_url = CharField(required=False) recovery_url = CharField(required=False)
@ -194,11 +195,12 @@ class IdentificationStageView(ChallengeStageView):
challenge = IdentificationChallenge( challenge = IdentificationChallenge(
data={ data={
"type": ChallengeTypes.NATIVE.value, "type": ChallengeTypes.NATIVE.value,
"primary_action": self.get_primary_action(),
"component": "ak-stage-identification", "component": "ak-stage-identification",
"primary_action": self.get_primary_action(),
"user_fields": current_stage.user_fields, "user_fields": current_stage.user_fields,
"password_fields": bool(current_stage.password_stage), "password_fields": bool(current_stage.password_stage),
"show_source_labels": current_stage.show_source_labels, "show_source_labels": current_stage.show_source_labels,
"flow_designation": self.executor.flow.designation,
} }
) )
# If the user has been redirected to us whilst trying to access an # If the user has been redirected to us whilst trying to access an

View File

@ -4347,6 +4347,11 @@
"title": "Object uniqueness field", "title": "Object uniqueness field",
"description": "Field which contains a unique Identifier." "description": "Field which contains a unique Identifier."
}, },
"password_login_update_internal_password": {
"type": "boolean",
"title": "Password login update internal password",
"description": "Update internal authentik password when login succeeds with LDAP"
},
"sync_users": { "sync_users": {
"type": "boolean", "type": "boolean",
"title": "Sync users" "title": "Sync users"

View File

@ -64,6 +64,7 @@ def release_lock(cursor: Cursor):
"""Release database lock""" """Release database lock"""
if not LOCKED: if not LOCKED:
return return
LOGGER.info("releasing database lock")
cursor.execute("SELECT pg_advisory_unlock(%s)", (ADV_LOCK_UID,)) cursor.execute("SELECT pg_advisory_unlock(%s)", (ADV_LOCK_UID,))

View File

@ -0,0 +1,12 @@
from lifecycle.migrate import BaseMigration
class Migration(BaseMigration):
def needs_migration(self) -> bool:
self.cur.execute(
"SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'template';"
)
return not bool(self.cur.rowcount)
def run(self):
self.cur.execute("CREATE SCHEMA IF NOT EXISTS template; COMMIT;")

44
poetry.lock generated
View File

@ -3351,13 +3351,13 @@ test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "tes
[[package]] [[package]]
name = "requests-oauthlib" name = "requests-oauthlib"
version = "1.4.0" version = "2.0.0"
description = "OAuthlib authentication support for Requests." description = "OAuthlib authentication support for Requests."
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=3.4"
files = [ files = [
{file = "requests-oauthlib-1.4.0.tar.gz", hash = "sha256:acee623221e4a39abcbb919312c8ff04bd44e7e417087fb4bd5e2a2f53d5e79a"}, {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"},
{file = "requests_oauthlib-1.4.0-py2.py3-none-any.whl", hash = "sha256:7a3130d94a17520169e38db6c8d75f2c974643788465ecc2e4b36d288bf13033"}, {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"},
] ]
[package.dependencies] [package.dependencies]
@ -3509,28 +3509,28 @@ pyasn1 = ">=0.1.3"
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.3.3" version = "0.3.4"
description = "An extremely fast Python linter and code formatter, written in Rust." description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:973a0e388b7bc2e9148c7f9be8b8c6ae7471b9be37e1cc732f8f44a6f6d7720d"}, {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"},
{file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa60d23269d6e2031129b053fdb4e5a7b0637fc6c9c0586737b962b2f834493"}, {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eca7ff7a47043cf6ce5c7f45f603b09121a7cc047447744b029d1b719278eb5"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7d3f6762217c1da954de24b4a1a70515630d29f71e268ec5000afe81377642d"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b24c19e8598916d9c6f5a5437671f55ee93c212a2c4c569605dc3842b6820386"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5a6cbf216b69c7090f0fe4669501a27326c34e119068c1494f35aaf4cc683778"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352e95ead6964974b234e16ba8a66dad102ec7bf8ac064a23f95371d8b198aab"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d6ab88c81c4040a817aa432484e838aaddf8bfd7ca70e4e615482757acb64f8"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"},
{file = "ruff-0.3.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79bca3a03a759cc773fca69e0bdeac8abd1c13c31b798d5bb3c9da4a03144a9f"}, {file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"},
{file = "ruff-0.3.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2700a804d5336bcffe063fd789ca2c7b02b552d2e323a336700abb8ae9e6a3f8"}, {file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"},
{file = "ruff-0.3.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd66469f1a18fdb9d32e22b79f486223052ddf057dc56dea0caaf1a47bdfaf4e"}, {file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"},
{file = "ruff-0.3.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45817af234605525cdf6317005923bf532514e1ea3d9270acf61ca2440691376"}, {file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"},
{file = "ruff-0.3.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0da458989ce0159555ef224d5b7c24d3d2e4bf4c300b85467b08c3261c6bc6a8"}, {file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"},
{file = "ruff-0.3.3-py3-none-win32.whl", hash = "sha256:f2831ec6a580a97f1ea82ea1eda0401c3cdf512cf2045fa3c85e8ef109e87de0"}, {file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"},
{file = "ruff-0.3.3-py3-none-win_amd64.whl", hash = "sha256:be90bcae57c24d9f9d023b12d627e958eb55f595428bafcb7fec0791ad25ddfc"}, {file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"},
{file = "ruff-0.3.3-py3-none-win_arm64.whl", hash = "sha256:0171aab5fecdc54383993389710a3d1227f2da124d76a2784a7098e818f92d61"}, {file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"},
{file = "ruff-0.3.3.tar.gz", hash = "sha256:38671be06f57a2f8aba957d9f701ea889aa5736be806f18c0cd03d6ff0cbca8d"}, {file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"},
] ]
[[package]] [[package]]

View File

@ -19926,6 +19926,10 @@ paths:
description: Number of results to return per page. description: Number of results to return per page.
schema: schema:
type: integer type: integer
- in: query
name: password_login_update_internal_password
schema:
type: boolean
- in: query - in: query
name: peer_certificate name: peer_certificate
schema: schema:
@ -31782,8 +31786,7 @@ components:
pk: pk:
type: string type: string
format: uuid format: uuid
readOnly: true title: Connection token uuid
title: Pbm uuid
provider: provider:
type: integer type: integer
provider_obj: provider_obj:
@ -31793,7 +31796,6 @@ components:
endpoint: endpoint:
type: string type: string
format: uuid format: uuid
readOnly: true
endpoint_obj: endpoint_obj:
allOf: allOf:
- $ref: '#/components/schemas/Endpoint' - $ref: '#/components/schemas/Endpoint'
@ -31805,7 +31807,6 @@ components:
required: required:
- endpoint - endpoint
- endpoint_obj - endpoint_obj
- pk
- provider - provider
- provider_obj - provider_obj
- user - user
@ -31813,9 +31814,17 @@ components:
type: object type: object
description: ConnectionToken Serializer description: ConnectionToken Serializer
properties: properties:
pk:
type: string
format: uuid
title: Connection token uuid
provider: provider:
type: integer type: integer
endpoint:
type: string
format: uuid
required: required:
- endpoint
- provider - provider
ConsentChallenge: ConsentChallenge:
type: object type: object
@ -34332,6 +34341,8 @@ components:
type: boolean type: boolean
application_pre: application_pre:
type: string type: string
flow_designation:
$ref: '#/components/schemas/FlowDesignationEnum'
enroll_url: enroll_url:
type: string type: string
recovery_url: recovery_url:
@ -34347,6 +34358,7 @@ components:
show_source_labels: show_source_labels:
type: boolean type: boolean
required: required:
- flow_designation
- password_fields - password_fields
- primary_action - primary_action
- show_source_labels - show_source_labels
@ -35217,6 +35229,10 @@ components:
object_uniqueness_field: object_uniqueness_field:
type: string type: string
description: Field which contains a unique Identifier. description: Field which contains a unique Identifier.
password_login_update_internal_password:
type: boolean
description: Update internal authentik password when login succeeds with
LDAP
sync_users: sync_users:
type: boolean type: boolean
sync_users_password: sync_users_password:
@ -35358,6 +35374,10 @@ components:
type: string type: string
minLength: 1 minLength: 1
description: Field which contains a unique Identifier. description: Field which contains a unique Identifier.
password_login_update_internal_password:
type: boolean
description: Update internal authentik password when login succeeds with
LDAP
sync_users: sync_users:
type: boolean type: boolean
sync_users_password: sync_users_password:
@ -38586,8 +38606,15 @@ components:
type: object type: object
description: ConnectionToken Serializer description: ConnectionToken Serializer
properties: properties:
pk:
type: string
format: uuid
title: Connection token uuid
provider: provider:
type: integer type: integer
endpoint:
type: string
format: uuid
PatchedConsentStageRequest: PatchedConsentStageRequest:
type: object type: object
description: ConsentStage Serializer description: ConsentStage Serializer
@ -39425,6 +39452,10 @@ components:
type: string type: string
minLength: 1 minLength: 1
description: Field which contains a unique Identifier. description: Field which contains a unique Identifier.
password_login_update_internal_password:
type: boolean
description: Update internal authentik password when login succeeds with
LDAP
sync_users: sync_users:
type: boolean type: boolean
sync_users_password: sync_users_password:
@ -45584,8 +45615,8 @@ components:
description: Get latest version from cache description: Get latest version from cache
readOnly: true readOnly: true
version_latest_valid: version_latest_valid:
type: boolean type: string
description: Latest version query is a valid non-default value description: Check if latest version is valid
readOnly: true readOnly: true
build_hash: build_hash:
type: string type: string

View File

@ -128,6 +128,7 @@ class TestSourceLDAPSamba(SeleniumTestCase):
base_dn="dc=test,dc=goauthentik,dc=io", base_dn="dc=test,dc=goauthentik,dc=io",
additional_user_dn="ou=users", additional_user_dn="ou=users",
additional_group_dn="ou=groups", additional_group_dn="ou=groups",
password_login_update_internal_password=True,
) )
source.property_mappings.set( source.property_mappings.set(
LDAPPropertyMapping.objects.filter( LDAPPropertyMapping.objects.filter(

122
web/package-lock.json generated
View File

@ -17,7 +17,7 @@
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.5", "@formatjs/intl-listformat": "^7.5.5",
"@fortawesome/fontawesome-free": "^6.5.1", "@fortawesome/fontawesome-free": "^6.5.1",
"@goauthentik/api": "^2024.2.2-1710521362", "@goauthentik/api": "^2024.2.2-1711369360",
"@lit-labs/task": "^3.1.0", "@lit-labs/task": "^3.1.0",
"@lit/context": "^1.1.0", "@lit/context": "^1.1.0",
"@lit/localize": "^0.12.1", "@lit/localize": "^0.12.1",
@ -25,7 +25,7 @@
"@open-wc/lit-helpers": "^0.7.0", "@open-wc/lit-helpers": "^0.7.0",
"@patternfly/elements": "^2.4.0", "@patternfly/elements": "^2.4.0",
"@patternfly/patternfly": "^4.224.2", "@patternfly/patternfly": "^4.224.2",
"@sentry/browser": "^7.107.0", "@sentry/browser": "^7.108.0",
"@webcomponents/webcomponentsjs": "^2.8.0", "@webcomponents/webcomponentsjs": "^2.8.0",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"chart.js": "^4.4.2", "chart.js": "^4.4.2",
@ -59,7 +59,7 @@
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0", "@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
"@lit/localize-tools": "^0.7.2", "@lit/localize-tools": "^0.7.2",
"@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-replace": "^5.0.5",
"@spotlightjs/spotlight": "^1.2.14", "@spotlightjs/spotlight": "^1.2.15",
"@storybook/addon-essentials": "^7.6.17", "@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-links": "^7.6.17", "@storybook/addon-links": "^7.6.17",
"@storybook/api": "^7.6.17", "@storybook/api": "^7.6.17",
@ -2820,9 +2820,9 @@
} }
}, },
"node_modules/@goauthentik/api": { "node_modules/@goauthentik/api": {
"version": "2024.2.2-1710521362", "version": "2024.2.2-1711369360",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.2.2-1710521362.tgz", "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.2.2-1711369360.tgz",
"integrity": "sha512-rfGIk+l+hcsgYd6Pj8cL9GTrUlJzT2dhAI6kJk7OsE/HamIUxpPG5wquE9oRcxrsWYkuFZQ1Z4lTePdSjxbt0w==" "integrity": "sha512-8/J6cfxzpaUyz+piZUXrxPZuAlJ9SxwNrH+Z8xSRLAVavmEjmRM+Oy2XJEIZLDbcBKhNEuE99xdOxq6il/FJVw=="
}, },
"node_modules/@hcaptcha/types": { "node_modules/@hcaptcha/types": {
"version": "1.0.3", "version": "1.0.3",
@ -4407,102 +4407,102 @@
"peer": true "peer": true
}, },
"node_modules/@sentry-internal/feedback": { "node_modules/@sentry-internal/feedback": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.108.0.tgz",
"integrity": "sha512-okF0B9AJHrpkwNMxNs/Lffw3N5ZNbGwz4uvCfyOfnMxc7E2VfDM18QzUvTBRvNr3bA9wl+InJ+EMG3aZhyPunA==", "integrity": "sha512-8JcgZEnk1uWrXJhsd3iRvFtEiVeaWOEhN0NZwhwQXHfvODqep6JtrkY1yCIyxbpA37aZmrPc2JhyotRERGfUjg==",
"dependencies": { "dependencies": {
"@sentry/core": "7.107.0", "@sentry/core": "7.108.0",
"@sentry/types": "7.107.0", "@sentry/types": "7.108.0",
"@sentry/utils": "7.107.0" "@sentry/utils": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@sentry-internal/replay-canvas": { "node_modules/@sentry-internal/replay-canvas": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.108.0.tgz",
"integrity": "sha512-dmDL9g3QDfo7axBOsVnpiKdJ/DXrdeuRv1AqsLgwzJKvItsv0ZizX0u+rj5b1UoxcwbXRMxJ0hit5a1yt3t/ow==", "integrity": "sha512-R5tvjGqWUV5vSk0N1eBgVW7wIADinrkfDEBZ9FyKP2mXHBobsyNGt30heJDEqYmVqluRqjU2NuIRapsnnrpGnA==",
"dependencies": { "dependencies": {
"@sentry/core": "7.107.0", "@sentry/core": "7.108.0",
"@sentry/replay": "7.107.0", "@sentry/replay": "7.108.0",
"@sentry/types": "7.107.0", "@sentry/types": "7.108.0",
"@sentry/utils": "7.107.0" "@sentry/utils": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@sentry-internal/tracing": { "node_modules/@sentry-internal/tracing": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.108.0.tgz",
"integrity": "sha512-le9wM8+OHBbq7m/8P7JUJ1UhSPIty+Z/HmRXc5Z64ODZcOwFV6TmDpYx729IXDdz36XUKmeI+BeM7yQdTTZPfQ==", "integrity": "sha512-zuK5XsTsb+U+hgn3SPetYDAogrXsM16U/LLoMW7+TlC6UjlHGYQvmX3o+M2vntejoU1QZS8m1bCAZSMWEypAEw==",
"dependencies": { "dependencies": {
"@sentry/core": "7.107.0", "@sentry/core": "7.108.0",
"@sentry/types": "7.107.0", "@sentry/types": "7.108.0",
"@sentry/utils": "7.107.0" "@sentry/utils": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/browser": { "node_modules/@sentry/browser": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.108.0.tgz",
"integrity": "sha512-KnqaQDhxv6w9dJ+mYLsNwPeGZfgbpM3vaismBNyJCKLgWn2V75kxkSq+bDX8LQT/13AyK7iFp317L6P8EuNa3g==", "integrity": "sha512-FNpzsdTvGvdHJMUelqEouUXMZU7jC+dpN7CdT6IoHVVFEkoAgrjMVUhXZoQ/dmCkdKWHmFSQhJ8Fm6V+e9Aq0A==",
"dependencies": { "dependencies": {
"@sentry-internal/feedback": "7.107.0", "@sentry-internal/feedback": "7.108.0",
"@sentry-internal/replay-canvas": "7.107.0", "@sentry-internal/replay-canvas": "7.108.0",
"@sentry-internal/tracing": "7.107.0", "@sentry-internal/tracing": "7.108.0",
"@sentry/core": "7.107.0", "@sentry/core": "7.108.0",
"@sentry/replay": "7.107.0", "@sentry/replay": "7.108.0",
"@sentry/types": "7.107.0", "@sentry/types": "7.108.0",
"@sentry/utils": "7.107.0" "@sentry/utils": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/core": { "node_modules/@sentry/core": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.108.0.tgz",
"integrity": "sha512-C7ogye6+KPyBi8NVL0P8Rxx3Ur7Td8ufnjxosVy678lqY+dcYPk/HONROrzUFYW5fMKWL4/KYnwP+x9uHnkDmw==", "integrity": "sha512-I/VNZCFgLASxHZaD0EtxZRM34WG9w2gozqgrKGNMzAymwmQ3K9g/1qmBy4e6iS3YRptb7J5UhQkZQHrcwBbjWQ==",
"dependencies": { "dependencies": {
"@sentry/types": "7.107.0", "@sentry/types": "7.108.0",
"@sentry/utils": "7.107.0" "@sentry/utils": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/replay": { "node_modules/@sentry/replay": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.108.0.tgz",
"integrity": "sha512-BNJDEVaEwr/YnV22qnyVA1almx/3p615m3+KaF8lPo7YleYgJGSJv1auH64j1G8INkrJ0J0wFBujb1EFjMYkxA==", "integrity": "sha512-jo8fDOzcZJclP1+4n9jUtVxTlBFT9hXwxhAMrhrt70FV/nfmCtYQMD3bzIj79nwbhUtFP6pN39JH1o7Xqt1hxQ==",
"dependencies": { "dependencies": {
"@sentry-internal/tracing": "7.107.0", "@sentry-internal/tracing": "7.108.0",
"@sentry/core": "7.107.0", "@sentry/core": "7.108.0",
"@sentry/types": "7.107.0", "@sentry/types": "7.108.0",
"@sentry/utils": "7.107.0" "@sentry/utils": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@sentry/types": { "node_modules/@sentry/types": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.108.0.tgz",
"integrity": "sha512-H7qcPjPSUWHE/Zf5bR1EE24G0pGVuJgrSx8Tvvl5nKEepswMYlbXHRVSDN0gTk/E5Z7cqf+hUBOpkQgZyps77w==", "integrity": "sha512-bKtHITmBN3kqtqE5eVvL8mY8znM05vEodENwRpcm6TSrrBjC2RnwNWVwGstYDdHpNfFuKwC8mLY9bgMJcENo8g==",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/utils": { "node_modules/@sentry/utils": {
"version": "7.107.0", "version": "7.108.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.107.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.108.0.tgz",
"integrity": "sha512-C6PbN5gHh73MRHohnReeQ60N8rrLYa9LciHue3Ru2290eSThg4CzsPnx4SzkGpkSeVlhhptKtKZ+hp/ha3iVuw==", "integrity": "sha512-a45yEFD5qtgZaIFRAcFkG8C8lnDzn6t4LfLXuV4OafGAy/3ZAN3XN8wDnrruHkiUezSSANGsLg3bXaLW/JLvJw==",
"dependencies": { "dependencies": {
"@sentry/types": "7.107.0" "@sentry/types": "7.108.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@ -4514,9 +4514,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@spotlightjs/overlay": { "node_modules/@spotlightjs/overlay": {
"version": "1.8.0", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-1.8.0.tgz", "resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-1.8.1.tgz",
"integrity": "sha512-yRcxp7Je4OXyr/JNJp5TAixu7gV9Hq99MQ94bMvoLv+WtS1ngd1lBmxMwAWKGp5TFUXCidNzKIjc11T4nCQ6FQ==", "integrity": "sha512-t8S2b6AxgDfDoPls3CU7uABLdKx3g8cCXQWEHOICC1i7MYUSQLFMDpWzFWTEjN0XA8MGwNf/QKNlZ/HhaKTzJw==",
"dev": true "dev": true
}, },
"node_modules/@spotlightjs/sidecar": { "node_modules/@spotlightjs/sidecar": {
@ -4528,12 +4528,12 @@
} }
}, },
"node_modules/@spotlightjs/spotlight": { "node_modules/@spotlightjs/spotlight": {
"version": "1.2.14", "version": "1.2.15",
"resolved": "https://registry.npmjs.org/@spotlightjs/spotlight/-/spotlight-1.2.14.tgz", "resolved": "https://registry.npmjs.org/@spotlightjs/spotlight/-/spotlight-1.2.15.tgz",
"integrity": "sha512-bix/qb0qnky3GajKAQ5gJquh81CPlc6/c6KmxCuZbH2pta0M5r9RmQbLFrZkJl9QvkHCf/+qBDrm1Td6KtRIoQ==", "integrity": "sha512-M0VTAyameAsK9kjI9k31CehTLJMqUdOvv7DSOr27dcioytBV0uC0l8w7ngHWxdqCOTpbruEs8EIrbQ0T9b4YZQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@spotlightjs/overlay": "1.8.0", "@spotlightjs/overlay": "1.8.1",
"@spotlightjs/sidecar": "1.4.0" "@spotlightjs/sidecar": "1.4.0"
}, },
"bin": { "bin": {

View File

@ -38,7 +38,7 @@
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.5", "@formatjs/intl-listformat": "^7.5.5",
"@fortawesome/fontawesome-free": "^6.5.1", "@fortawesome/fontawesome-free": "^6.5.1",
"@goauthentik/api": "^2024.2.2-1710521362", "@goauthentik/api": "^2024.2.2-1711369360",
"@lit-labs/task": "^3.1.0", "@lit-labs/task": "^3.1.0",
"@lit/context": "^1.1.0", "@lit/context": "^1.1.0",
"@lit/localize": "^0.12.1", "@lit/localize": "^0.12.1",
@ -46,7 +46,7 @@
"@open-wc/lit-helpers": "^0.7.0", "@open-wc/lit-helpers": "^0.7.0",
"@patternfly/elements": "^2.4.0", "@patternfly/elements": "^2.4.0",
"@patternfly/patternfly": "^4.224.2", "@patternfly/patternfly": "^4.224.2",
"@sentry/browser": "^7.107.0", "@sentry/browser": "^7.108.0",
"@webcomponents/webcomponentsjs": "^2.8.0", "@webcomponents/webcomponentsjs": "^2.8.0",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"chart.js": "^4.4.2", "chart.js": "^4.4.2",
@ -80,7 +80,7 @@
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0", "@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
"@lit/localize-tools": "^0.7.2", "@lit/localize-tools": "^0.7.2",
"@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-replace": "^5.0.5",
"@spotlightjs/spotlight": "^1.2.14", "@spotlightjs/spotlight": "^1.2.15",
"@storybook/addon-essentials": "^7.6.17", "@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-links": "^7.6.17", "@storybook/addon-links": "^7.6.17",
"@storybook/api": "^7.6.17", "@storybook/api": "^7.6.17",

View File

@ -175,7 +175,7 @@ export class OAuth2ProviderViewPage extends AKElement {
</div>`} </div>`}
<div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter"> <div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
<div <div
class="pf-c-card pf-l-grid__item pf-l-grid__item pf-m-12-col pf-m-3-col-on-xl pf-m-3-col-on-2xl" class="pf-c-card pf-l-grid__item pf-l-grid__item pf-m-12-col pf-m-4-col-on-xl pf-m-4-col-on-2xl"
> >
<div class="pf-c-card__body"> <div class="pf-c-card__body">
<dl class="pf-c-description-list"> <dl class="pf-c-description-list">
@ -255,7 +255,7 @@ export class OAuth2ProviderViewPage extends AKElement {
</ak-forms-modal> </ak-forms-modal>
</div> </div>
</div> </div>
<div class="pf-c-card pf-l-grid__item pf-m-7-col"> <div class="pf-c-card pf-l-grid__item pf-m-8-col">
<div class="pf-c-card__body"> <div class="pf-c-card__body">
<form class="pf-c-form"> <form class="pf-c-form">
<div class="pf-c-form__group"> <div class="pf-c-form__group">

View File

@ -61,12 +61,12 @@ export class ConnectionTokenListPage extends Table<ConnectionToken> {
}} }}
.usedBy=${(item: ConnectionToken) => { .usedBy=${(item: ConnectionToken) => {
return new RacApi(DEFAULT_CONFIG).racConnectionTokensUsedByList({ return new RacApi(DEFAULT_CONFIG).racConnectionTokensUsedByList({
connectionTokenUuid: item.pk, connectionTokenUuid: item.pk || "",
}); });
}} }}
.delete=${(item: ConnectionToken) => { .delete=${(item: ConnectionToken) => {
return new RacApi(DEFAULT_CONFIG).racConnectionTokensDestroy({ return new RacApi(DEFAULT_CONFIG).racConnectionTokensDestroy({
connectionTokenUuid: item.pk, connectionTokenUuid: item.pk || "",
}); });
}} }}
> >

View File

@ -86,6 +86,28 @@ export class LDAPSourceForm extends BaseSourceForm<LDAPSource> {
<span class="pf-c-switch__label">${msg("Enabled")}</span> <span class="pf-c-switch__label">${msg("Enabled")}</span>
</label> </label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="passwordLoginUpdateInternalPassword">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.passwordLoginUpdateInternalPassword, false)}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label"
>${msg("Update internal password on login")}</span
>
</label>
<p class="pf-c-form__helper-text">
${msg(
"When the user logs in to authentik using this source password backend, update their credentials in authentik.",
)}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="syncUsers"> <ak-form-element-horizontal name="syncUsers">
<label class="pf-c-switch"> <label class="pf-c-switch">
<input <input

View File

@ -1,5 +1,6 @@
import { PFSize } from "@goauthentik/common/enums.js"; import { PFSize } from "@goauthentik/common/enums.js";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/Spinner";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";

View File

@ -0,0 +1,58 @@
import type { StoryObj } from "@storybook/web-components";
import { html } from "lit";
import "@patternfly/patternfly/components/Login/login.css";
import { AuthenticatorTOTPChallenge, ChallengeChoices, UiThemeEnum } from "@goauthentik/api";
import "../../../stories/flow-interface";
import "./AuthenticatorTOTPStage";
export default {
title: "Flow / Stages / AuthenticatorTOTPStage",
};
export const LoadingNoChallenge = () => {
return html`<ak-storybook-interface theme=${UiThemeEnum.Dark}>
<div class="pf-c-login">
<div class="pf-c-login__container">
<div class="pf-c-login__main">
<ak-stage-authenticator-totp></ak-stage-authenticator-totp>
</div>
</div>
</div>
</ak-storybook-interface>`;
};
export const Challenge: StoryObj = {
render: ({ theme, challenge }) => {
return html`<ak-storybook-interface theme=${theme}>
<div class="pf-c-login">
<div class="pf-c-login__container">
<div class="pf-c-login__main">
<ak-stage-authenticator-totp
.challenge=${challenge}
></ak-stage-authenticator-totp>
</div>
</div></div
></ak-storybook-interface>`;
},
args: {
theme: "automatic",
challenge: {
type: ChallengeChoices.Native,
pendingUser: "foo",
pendingUserAvatar: "https://picsum.photos/64",
configUrl: "",
} as AuthenticatorTOTPChallenge,
},
argTypes: {
theme: {
options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
control: {
type: "select",
},
},
},
};

View File

@ -106,6 +106,11 @@ export class AuthenticatorTOTPStage extends BaseStage<
</button> </button>
</div> </div>
</ak-form-element> </ak-form-element>
<p>
${msg(
"Please scan the QR code above using the Microsoft Authenticator, Google Authenticator, or other authenticator apps on your device, and enter the code the device displays below to finish setting up the MFA device.",
)}
</p>
<ak-form-element <ak-form-element
label="${msg("Code")}" label="${msg("Code")}"
?required="${true}" ?required="${true}"

View File

@ -5,7 +5,7 @@ import "@goauthentik/elements/forms/FormElement";
import { BaseStage } from "@goauthentik/flow/stages/base"; import { BaseStage } from "@goauthentik/flow/stages/base";
import { msg, str } from "@lit/localize"; import { msg, str } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html, nothing } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
@ -17,6 +17,7 @@ import PFTitle from "@patternfly/patternfly/components/Title/title.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { import {
FlowDesignationEnum,
IdentificationChallenge, IdentificationChallenge,
IdentificationChallengeResponseRequest, IdentificationChallengeResponseRequest,
LoginSource, LoginSource,
@ -220,7 +221,16 @@ export class IdentificationStage extends BaseStage<
[UserFieldsEnum.Upn]: msg("UPN"), [UserFieldsEnum.Upn]: msg("UPN"),
}; };
const label = OR_LIST_FORMATTERS.format(fields.map((f) => uiFields[f])); const label = OR_LIST_FORMATTERS.format(fields.map((f) => uiFields[f]));
return html`<ak-form-element return html`${this.challenge.flowDesignation === FlowDesignationEnum.Recovery
? html`
<p>
${msg(
"Enter the email associated with your account, and we'll send you a link to reset your password.",
)}
</p>
`
: nothing}
<ak-form-element
label=${label} label=${label}
?required="${true}" ?required="${true}"
class="pf-c-form__group" class="pf-c-form__group"

View File

@ -2,7 +2,7 @@
title: "Templates" title: "Templates"
--- ---
In technical documentation, there are document "types" (similar to how there are data types). In technical documentation, there are document "types" (similar to how there are data types). We have templates for the different types, to make it super-easy for whomever wants to contribute some documentation!
The most common types are: The most common types are:
@ -14,4 +14,10 @@ The most common types are:
- [**Reference**](./reference.md): this is typically tables or lists of reference information, such as configuration values, or functions, or most commmonly APIs. - [**Reference**](./reference.md): this is typically tables or lists of reference information, such as configuration values, or functions, or most commmonly APIs.
We have templates for the different types, to make it super-easy for whomever wants to contribute some documentation! ### Add a new integration
To add documentation for a new [integration](../../../integrations/) (with support level Community or Vendor), please use the integration template [`service.md`](https://github.com/goauthentik/authentik/blob/main/website/integrations/_template/service.md) file from our GitHub repo. You can download the template file using the following command:
```
wget https://raw.githubusercontent.com/goauthentik/authentik/main/website/integrations/_template/service.md
```

View File

@ -5,9 +5,14 @@ title: Inspector
The flow inspector, introduced in 2021.10, allows administrators to easily figure out how custom flows work, inspect the current context and debug issues. The flow inspector, introduced in 2021.10, allows administrators to easily figure out how custom flows work, inspect the current context and debug issues.
:::info :::info
When running a flow with the inspector enabled, the flow is still executed normally. This means that for example, a `user_write` stage will _actually_ write user data. When running a flow with the inspector enabled, the flow is still executed normally. This means that for example, a [User write](../flow/stages/user_write.md) stage will _actually_ write user data.
::: :::
### Accessing the inspector
By default, the inspector can only be enabled when the currently authenticated user is a superuser.
When developing authentik with the debug-mode enabled, the inspector is enabled by default and can be accessed by both unauthenticated users and standard users. However the debug-mode should only be used for the development of authentik.
![](./inspector.png) ![](./inspector.png)
The following infos are shown in the inspector The following infos are shown in the inspector
@ -31,7 +36,3 @@ This data is not cleaned, so if your flow involves inputting a password, it will
## Session ID ## Session ID
The unique ID for the currently used session. This can be used to debug issues with flows restarting/losing state. The unique ID for the currently used session. This can be used to debug issues with flows restarting/losing state.
# Access to the inspector
By default, the inspector can only be enabled when the currently authenticated user is a superuser. When running authentik with debug-mode enabled, the inspector is enabled by default and can be accessed by both unauthenticated users and standard users.

View File

@ -56,7 +56,7 @@ server {
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host; proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade_keepalive; proxy_set_header Connection $connection_upgrade_keepalive;
} }

View File

@ -6,20 +6,25 @@ slug: /
import DocCardList from "@theme/DocCardList"; import DocCardList from "@theme/DocCardList";
import { useCurrentSidebarCategory } from "@docusaurus/theme-common"; import { useCurrentSidebarCategory } from "@docusaurus/theme-common";
Below is a list of all applications that are known to work with authentik. Below is a list of all integrations, or applications that are known to work with authentik. All integrations will have one of these badges:
All integrations will have a combination of these badges: - <span class="badge badge--secondary">Support level: Community</span> The integration
is community maintained.
- <span class="badge badge--secondary">Support level: Community</span> - <span class="badge badge--info">Support level: Vendor</span> The integration
is supported by the vendor.
The integration is community maintained. - <span class="badge badge--primary">Support level: authentik</span> The integration
is regularly tested by the authentik team.
- <span class="badge badge--info">Support level: Vendor</span> ### Add a new integration
The integration is supported by the vendor. To add documentation for a new integration (with support level Community or Vendor), please use the integration template [`service.md`](https://github.com/goauthentik/authentik/blob/main/website/integrations/_template/service.md) file from our GitHub repo. You can download the template file using the following command:
- <span class="badge badge--primary">Support level: authentik</span> ```
wget https://raw.githubusercontent.com/goauthentik/authentik/main/website/integrations/_template/service.md
```
The integration is regularly tested by the authentik team. ## Integration categories
<DocCardList items={useCurrentSidebarCategory().items} /> <DocCardList items={useCurrentSidebarCategory().items} />

View File

@ -286,7 +286,7 @@ Create a custom SAML Property Mapping:
- Set the _Expression_ to: - Set the _Expression_ to:
```python ```python
for group in user.ak_groups.all(): for group in request.user.all_groups():
yield group.name yield group.name
if ak_is_group_member(request.user, name="<authentik nextcloud admin group's name>"): if ak_is_group_member(request.user, name="<authentik nextcloud admin group's name>"):
yield "admin" yield "admin"

View File

@ -14,25 +14,25 @@ For Active Directory, follow the [Active Directory Integration](../active-direct
For FreeIPA, follow the [FreeIPA Integration](../freeipa/) For FreeIPA, follow the [FreeIPA Integration](../freeipa/)
::: :::
- Server URI: URI to your LDAP server/Domain Controller. - **Server URI**: URI to your LDAP server/Domain Controller.
You can specify multiple servers by separating URIs with a comma, like `ldap://ldap1.company,ldap://ldap2.company`. You can specify multiple servers by separating URIs with a comma, like `ldap://ldap1.company,ldap://ldap2.company`.
When using a DNS entry with multiple Records, authentik will select a random entry when first connecting. When using a DNS entry with multiple Records, authentik will select a random entry when first connecting.
- Bind CN: CN of the bind user. This can also be a UPN in the format of `user@domain.tld`. - **Bind CN**: CN of the bind user. This can also be a UPN in the format of `user@domain.tld`.
- Bind password: Password used during the bind process. - **Bind password**: Password used during the bind process.
- Enable StartTLS: Enables StartTLS functionality. To use LDAPS instead, use port `636`. - **Enable StartTLS**: Enables StartTLS functionality. To use LDAPS instead, use port `636`.
- Base DN: Base DN used for all LDAP queries. - **Base DN**: Base DN used for all LDAP queries.
- Addition User DN: Prepended to the base DN for user queries. - **Addition User DN**: Prepended to the base DN for user queries.
- Addition Group DN: Prepended to the base DN for group queries. - **Addition Group DN**: Prepended to the base DN for group queries.
- User object filter: Consider objects matching this filter to be users. - **User object filter**: Consider objects matching this filter to be users.
- Group object filter: Consider objects matching this filter to be groups. - **Group object filter**: Consider objects matching this filter to be groups.
- User group membership field: This field contains the user's group memberships. - **User group membership field**: This field contains the user's group memberships.
- Object uniqueness field: This field contains a unique identifier. - **Object uniqueness field**: This field contains a unique identifier.
- Sync groups: Enable/disable group synchronization. Groups are synced in the background every 5 minutes. - **Sync groups**: Enable/disable group synchronization. Groups are synced in the background every 5 minutes.
- Sync parent group: Optionally set this group as the parent group for all synced groups. An example use case of this would be to import Active Directory groups under a root `imported-from-ad` group. - **Sync parent group**: Optionally set this group as the parent group for all synced groups. An example use case of this would be to import Active Directory groups under a root `imported-from-ad` group.
- Property mappings: Define which LDAP properties map to which authentik properties. The default set of property mappings is generated for Active Directory. See also [LDAP Property Mappings](../../../docs/property-mappings/#ldap-property-mapping) - **Property mappings** and **Group Property Mappings**: Define which LDAP properties map to which authentik properties. The default set of property mappings is generated for Active Directory. See also [LDAP Property Mappings](../../../docs/property-mappings/#ldap-property-mapping)
## Property mappings ## Property mappings
@ -42,6 +42,20 @@ By default, authentik ships with some pre-configured mappings for the most commo
You can assign the value of a mapping to any user attribute, or save it as a custom attribute by prefixing the object field with `attribute.` Keep in mind though, data types from the LDAP server will be carried over. This means that with some implementations, where fields are stored as array in LDAP, they will be saved as array in authentik. To prevent this, use the built-in `list_flatten` function. You can assign the value of a mapping to any user attribute, or save it as a custom attribute by prefixing the object field with `attribute.` Keep in mind though, data types from the LDAP server will be carried over. This means that with some implementations, where fields are stored as array in LDAP, they will be saved as array in authentik. To prevent this, use the built-in `list_flatten` function.
## Password login
By default, authentik doesn't update the password it stores for a user when they log in using their LDAP credentials. That means that if the LDAP server is not reachable by authentik, users will not be able to log in. This behavior can be turned on with the **Update internal password on login** setting on the LDAP source.
:::note
Sources created prior to the 2024.2 release have this setting turned on by default.
:::
Be aware of the following security considerations when turning on this functionality:
- Updating the LDAP password does not invalid the password stored in authentik, however for LDAP Servers like FreeIPA and Active Directory, authentik will lock its internal password during the next LDAP sync. For other LDAP servers, the old passwords will still be valid indefinitely.
- Logging in via LDAP credentials overwrites the password stored in authentik if users have different passwords in LDAP and authentik.
- Custom security measures used to secure the password in LDAP may differ from the ones used in authentik. Depending on thread model and security requirements this could lead to unknowingly being non-compliant.
## Troubleshooting ## Troubleshooting
To troubleshoot LDAP sources and their synchronization, see [LDAP Troubleshooting](../../../docs/troubleshooting/ldap_source) To troubleshoot LDAP sources and their synchronization, see [LDAP Troubleshooting](../../../docs/troubleshooting/ldap_source)

View File

@ -33,7 +33,7 @@
"@docusaurus/module-type-aliases": "3.1.1", "@docusaurus/module-type-aliases": "3.1.1",
"@docusaurus/tsconfig": "3.1.1", "@docusaurus/tsconfig": "3.1.1",
"@docusaurus/types": "3.1.1", "@docusaurus/types": "3.1.1",
"@types/react": "^18.2.67", "@types/react": "^18.2.69",
"prettier": "3.2.5", "prettier": "3.2.5",
"typescript": "~5.4.3" "typescript": "~5.4.3"
}, },
@ -3999,9 +3999,9 @@
"integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==" "integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA=="
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "18.2.67", "version": "18.2.69",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.67.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.69.tgz",
"integrity": "sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==", "integrity": "sha512-W1HOMUWY/1Yyw0ba5TkCV+oqynRjG7BnteBB+B7JmAK7iw3l2SW+VGOxL+akPweix6jk2NNJtyJKpn4TkpfK3Q==",
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -16568,9 +16568,9 @@
} }
}, },
"node_modules/webpack-dev-middleware": { "node_modules/webpack-dev-middleware": {
"version": "5.3.3", "version": "5.3.4",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
"integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
"dependencies": { "dependencies": {
"colorette": "^2.0.10", "colorette": "^2.0.10",
"memfs": "^3.4.3", "memfs": "^3.4.3",

View File

@ -52,7 +52,7 @@
"@docusaurus/module-type-aliases": "3.1.1", "@docusaurus/module-type-aliases": "3.1.1",
"@docusaurus/tsconfig": "3.1.1", "@docusaurus/tsconfig": "3.1.1",
"@docusaurus/types": "3.1.1", "@docusaurus/types": "3.1.1",
"@types/react": "^18.2.67", "@types/react": "^18.2.69",
"prettier": "3.2.5", "prettier": "3.2.5",
"typescript": "~5.4.3" "typescript": "~5.4.3"
}, },