start working on new implementation
@@ -3,7 +3,7 @@ from pathlib import Path
|
||||
|
||||
from django.http.request import HttpRequest
|
||||
|
||||
from authentik.admin.files.backends.base import Backend
|
||||
from authentik.admin.files.backends.base import Backend, THEME_VARIABLE
|
||||
from authentik.admin.files.usage import FileUsage
|
||||
from authentik.lib.config import CONFIG
|
||||
|
||||
@@ -35,6 +35,20 @@ class StaticBackend(Backend):
|
||||
for file_path in STATIC_ASSETS_SOURCES_DIR.iterdir():
|
||||
if file_path.is_file() and (file_path.suffix in STATIC_FILE_EXTENSIONS):
|
||||
yield f"{STATIC_PATH_PREFIX}/authentik/sources/{file_path.name}"
|
||||
continue
|
||||
|
||||
if not file_path.is_dir():
|
||||
continue
|
||||
|
||||
for extension in STATIC_FILE_EXTENSIONS:
|
||||
light_variant = file_path / f"light{extension}"
|
||||
dark_variant = file_path / f"dark{extension}"
|
||||
if light_variant.exists() and dark_variant.exists():
|
||||
yield (
|
||||
f"{STATIC_PATH_PREFIX}/authentik/sources/"
|
||||
f"{file_path.name}/{THEME_VARIABLE}{extension}"
|
||||
)
|
||||
break
|
||||
|
||||
# List other static assets
|
||||
for dir in STATIC_ASSETS_DIRS:
|
||||
|
||||
@@ -37,6 +37,7 @@ class TestStaticBackend(TestCase):
|
||||
"""Test list_files includes expected files"""
|
||||
files = list(self.backend.list_files())
|
||||
|
||||
self.assertIn("/static/authentik/sources/github/%(theme)s.svg", files)
|
||||
self.assertIn("/static/authentik/sources/ldap.png", files)
|
||||
self.assertIn("/static/authentik/sources/openidconnect.svg", files)
|
||||
self.assertIn("/static/authentik/sources/saml.png", files)
|
||||
|
||||
@@ -219,6 +219,31 @@ class TestFileAPI(FileTestFileBackendMixin, TestCase):
|
||||
|
||||
manager.delete_file(file_name)
|
||||
|
||||
def test_list_files_includes_themed_urls_for_static_themed_icons(self):
|
||||
"""Test listing static themed icons exposes a %(theme)s placeholder entry."""
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"authentik_api:files",
|
||||
query={
|
||||
"search": "github/%(theme)s.svg",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn(
|
||||
{
|
||||
"name": "/static/authentik/sources/github/%(theme)s.svg",
|
||||
"url": "http://testserver/static/authentik/sources/github/%(theme)s.svg",
|
||||
"mime_type": "image/svg+xml",
|
||||
"themed_urls": {
|
||||
"light": "http://testserver/static/authentik/sources/github/light.svg",
|
||||
"dark": "http://testserver/static/authentik/sources/github/dark.svg",
|
||||
},
|
||||
},
|
||||
response.data,
|
||||
)
|
||||
|
||||
def test_list_files_includes_themed_urls_dict(self):
|
||||
"""Test listing files includes themed_urls as dict for themed files"""
|
||||
manager = FileManager(FileUsage.MEDIA)
|
||||
|
||||
@@ -9,7 +9,7 @@ from rest_framework.fields import (
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.core.api.utils import PassiveSerializer, ThemedUrlsSerializer
|
||||
from authentik.lib.models import DeprecatedMixin
|
||||
from authentik.lib.utils.reflection import all_subclasses
|
||||
|
||||
@@ -22,7 +22,8 @@ class TypeCreateSerializer(PassiveSerializer):
|
||||
component = CharField(required=True)
|
||||
model_name = CharField(required=True)
|
||||
|
||||
icon_url = CharField(required=False)
|
||||
icon_url = CharField(required=False, allow_null=True)
|
||||
icon_themed_urls = ThemedUrlsSerializer(required=False, allow_null=True)
|
||||
requires_enterprise = BooleanField(default=False)
|
||||
deprecated = BooleanField(default=False)
|
||||
|
||||
@@ -66,6 +67,7 @@ class TypesMixin:
|
||||
"component": instance.component,
|
||||
"model_name": subclass._meta.model_name,
|
||||
"icon_url": getattr(instance, "icon_url", None),
|
||||
"icon_themed_urls": getattr(instance, "icon_themed_urls", None),
|
||||
"requires_enterprise": False,
|
||||
"deprecated": isinstance(instance, DeprecatedMixin),
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@ from django.contrib.auth.hashers import check_password
|
||||
from django.contrib.auth.models import AbstractUser, Permission
|
||||
from django.contrib.auth.models import UserManager as DjangoUserManager
|
||||
from django.contrib.sessions.base_session import AbstractBaseSession
|
||||
from django.contrib.staticfiles import finders
|
||||
from django.core.validators import validate_slug
|
||||
from django.db import models
|
||||
from django.db.models import Manager, Q, QuerySet, options
|
||||
from django.http import HttpRequest
|
||||
from django.templatetags.static import static
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -58,6 +60,27 @@ USER_PATH_SYSTEM_PREFIX = "goauthentik.io"
|
||||
_USER_ATTR_PREFIX = f"{USER_PATH_SYSTEM_PREFIX}/user"
|
||||
USER_ATTRIBUTE_DEBUG = f"{_USER_ATTR_PREFIX}/debug"
|
||||
USER_ATTRIBUTE_GENERATED = f"{_USER_ATTR_PREFIX}/generated"
|
||||
|
||||
|
||||
def _get_default_source_icon_themed_urls(icon_name: str) -> dict[str, str] | None:
|
||||
themed_paths = {
|
||||
"light": f"authentik/sources/{icon_name}/light.svg",
|
||||
"dark": f"authentik/sources/{icon_name}/dark.svg",
|
||||
}
|
||||
if all(finders.find(path) for path in themed_paths.values()):
|
||||
return {theme: static(path) for theme, path in themed_paths.items()}
|
||||
|
||||
for extension in ("svg", "png"):
|
||||
legacy_path = f"authentik/sources/{icon_name}.{extension}"
|
||||
if finders.find(legacy_path):
|
||||
legacy_url = static(legacy_path)
|
||||
return {
|
||||
"light": legacy_url,
|
||||
"dark": legacy_url,
|
||||
}
|
||||
return None
|
||||
|
||||
|
||||
USER_ATTRIBUTE_EXPIRES = f"{_USER_ATTR_PREFIX}/expires"
|
||||
USER_ATTRIBUTE_DELETE_ON_LOGOUT = f"{_USER_ATTR_PREFIX}/delete-on-logout"
|
||||
USER_ATTRIBUTE_SOURCES = f"{_USER_ATTR_PREFIX}/sources"
|
||||
@@ -951,34 +974,46 @@ class Source(ManagedModel, SerializerModel, PolicyBindingModel):
|
||||
|
||||
objects = InheritanceManager()
|
||||
|
||||
def get_icon_url(self, request=None, use_cache: bool = True) -> str | None:
|
||||
"""Get the URL to the source icon."""
|
||||
if not self.icon:
|
||||
return None
|
||||
return get_file_manager(FileUsage.MEDIA).file_url(self.icon, request, use_cache=use_cache)
|
||||
default_icon_name: str | None = None
|
||||
"""Source type name used to resolve built-in themed icons (e.g. "discord")."""
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str | None:
|
||||
"""Get the URL to the source icon"""
|
||||
return self.get_icon_url()
|
||||
|
||||
def get_icon_themed_urls(
|
||||
self,
|
||||
request=None,
|
||||
use_cache: bool = True,
|
||||
) -> dict[str, str] | None:
|
||||
"""Get themed URLs for icon if it contains %(theme)s."""
|
||||
if not self.icon:
|
||||
return None
|
||||
return get_file_manager(FileUsage.MEDIA).themed_urls(
|
||||
self.icon,
|
||||
request,
|
||||
use_cache=use_cache,
|
||||
)
|
||||
"""Get the URL to the source icon."""
|
||||
manager = get_file_manager(FileUsage.MEDIA)
|
||||
custom_icon = None
|
||||
try:
|
||||
custom_icon = self.icon
|
||||
except AttributeError:
|
||||
# Abstract type instances (created via __new__) don't have field state.
|
||||
custom_icon = None
|
||||
if custom_icon:
|
||||
return manager.file_url(custom_icon)
|
||||
if self.default_icon_name:
|
||||
return _get_default_source_icon_url(self.default_icon_name)
|
||||
return None
|
||||
|
||||
@property
|
||||
def icon_themed_urls(self) -> dict[str, str] | None:
|
||||
return self.get_icon_themed_urls()
|
||||
"""Get themed URLs for source icon."""
|
||||
manager = get_file_manager(FileUsage.MEDIA)
|
||||
# If the user set a custom icon, check if it supports themes.
|
||||
custom_icon = None
|
||||
try:
|
||||
custom_icon = self.icon
|
||||
except AttributeError:
|
||||
# Abstract type instances (created via __new__) don't have field state.
|
||||
custom_icon = None
|
||||
if custom_icon:
|
||||
return manager.themed_urls(custom_icon)
|
||||
# Fall back to built-in default icons.
|
||||
if self.default_icon_name:
|
||||
return _get_default_source_icon_themed_urls(self.default_icon_name)
|
||||
return None
|
||||
|
||||
@property
|
||||
def icon_dynamic_url(self) -> dict[str, str] | None:
|
||||
return _build_dynamic_url_map(self.icon_url, self.icon_themed_urls)
|
||||
|
||||
def get_user_path(self) -> str:
|
||||
"""Get user path, fallback to default for formatting errors"""
|
||||
|
||||
@@ -4,7 +4,7 @@ from dataclasses import dataclass
|
||||
|
||||
from rest_framework.fields import CharField
|
||||
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.core.api.utils import PassiveSerializer, ThemedUrlsSerializer
|
||||
from authentik.flows.challenge import Challenge
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ class UILoginButton:
|
||||
# Icon URL, used as-is
|
||||
icon_url: str | None = None
|
||||
|
||||
# Pre-resolved themed icon URLs for light/dark variants
|
||||
icon_themed_urls: dict[str, str] | None = None
|
||||
|
||||
# Whether this source should be displayed as a prominent button
|
||||
promoted: bool = False
|
||||
|
||||
@@ -32,4 +35,5 @@ class UserSettingSerializer(PassiveSerializer):
|
||||
component = CharField()
|
||||
title = CharField(required=True)
|
||||
configure_url = CharField(required=False)
|
||||
icon_url = CharField(required=False)
|
||||
icon_url = CharField(required=False, allow_null=True)
|
||||
icon_themed_urls = ThemedUrlsSerializer(required=False, allow_null=True)
|
||||
|
||||
@@ -11,7 +11,6 @@ import pglock
|
||||
from django.db import connection, models
|
||||
from django.http import HttpRequest
|
||||
from django.shortcuts import reverse
|
||||
from django.templatetags.static import static
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from kadmin import KAdm5Variant, KAdmin, KAdminApiVersion
|
||||
@@ -129,12 +128,7 @@ class KerberosSource(IncomingSyncSource):
|
||||
def property_mapping_type(self) -> type[PropertyMapping]:
|
||||
return KerberosSourcePropertyMapping
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str:
|
||||
icon = super().icon_url
|
||||
if not icon:
|
||||
return static("authentik/sources/kerberos.png")
|
||||
return icon
|
||||
default_icon_name = "kerberos"
|
||||
|
||||
@property
|
||||
def schedule_specs(self) -> list[ScheduleSpec]:
|
||||
@@ -168,7 +162,7 @@ class KerberosSource(IncomingSyncSource):
|
||||
}
|
||||
),
|
||||
name=self.name,
|
||||
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
|
||||
icon_url=self.icon_dynamic_url,
|
||||
promoted=self.promoted,
|
||||
)
|
||||
|
||||
@@ -181,7 +175,7 @@ class KerberosSource(IncomingSyncSource):
|
||||
"authentik_sources_kerberos:spnego-login",
|
||||
kwargs={"source_slug": self.slug},
|
||||
),
|
||||
"icon_url": self.icon_url,
|
||||
"icon_url": self.icon_dynamic_url,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ from typing import Any
|
||||
|
||||
import pglock
|
||||
from django.db import connection, models
|
||||
from django.templatetags.static import static
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from ldap3 import ALL, NONE, RANDOM, Connection, Server, ServerPool, Tls
|
||||
from ldap3.core.exceptions import LDAPException, LDAPInsufficientAccessRightsResult, LDAPSchemaError
|
||||
@@ -211,9 +210,7 @@ class LDAPSource(IncomingSyncSource):
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str:
|
||||
return static("authentik/sources/ldap.png")
|
||||
default_icon_name = "ldap"
|
||||
|
||||
def server(self, **kwargs) -> ServerPool:
|
||||
"""Get LDAP Server/ServerPool"""
|
||||
|
||||
@@ -15,6 +15,7 @@ from authentik.core.models import (
|
||||
PropertyMapping,
|
||||
Source,
|
||||
UserSourceConnection,
|
||||
_get_default_source_icon_themed_urls,
|
||||
)
|
||||
from authentik.core.types import UILoginButton, UserSettingSerializer
|
||||
|
||||
@@ -112,23 +113,23 @@ class OAuthSource(NonCreatableType, Source):
|
||||
return self.source_type().get_base_group_properties(source=self, **kwargs)
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str | None:
|
||||
# When listing source types, this property might be retrieved from an abstract
|
||||
# model. In that case we can't check self.provider_type or self.icon_url
|
||||
# and as such we attempt to find the correct provider type based on the mode name
|
||||
if self.Meta.abstract:
|
||||
from authentik.sources.oauth.types.registry import registry
|
||||
def icon_themed_urls(self) -> dict[str, str] | None:
|
||||
"""Get themed URLs for source icon.
|
||||
|
||||
provider_type = registry.find_type(
|
||||
self._meta.model_name.replace(OAuthSource._meta.model_name, "")
|
||||
)
|
||||
return provider_type().icon_url()
|
||||
icon = super().icon_url
|
||||
if not icon:
|
||||
provider_type = self.source_type
|
||||
provider = provider_type()
|
||||
icon = provider.icon_url()
|
||||
return icon
|
||||
OAuth source types are abstract models so the DB always stores OAuthSource
|
||||
instances. We resolve the built-in icon from the provider_type field instead
|
||||
of the class-level default_icon_name (which only exists on the abstract
|
||||
subclasses used by the TypeCreate wizard).
|
||||
"""
|
||||
urls = super().icon_themed_urls
|
||||
if urls:
|
||||
return urls
|
||||
try:
|
||||
if self.provider_type:
|
||||
return _get_default_source_icon_themed_urls(self.provider_type)
|
||||
except AttributeError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def ui_login_button(self, request: HttpRequest) -> UILoginButton:
|
||||
provider_type = self.source_type
|
||||
@@ -136,7 +137,7 @@ class OAuthSource(NonCreatableType, Source):
|
||||
return UILoginButton(
|
||||
name=self.name,
|
||||
challenge=provider.login_challenge(self, request),
|
||||
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
|
||||
icon_url=self.icon_dynamic_url,
|
||||
promoted=self.promoted,
|
||||
)
|
||||
|
||||
@@ -150,6 +151,7 @@ class OAuthSource(NonCreatableType, Source):
|
||||
kwargs={"source_slug": self.slug},
|
||||
),
|
||||
"icon_url": self.icon_url,
|
||||
"icon_themed_urls": self.icon_themed_urls,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -164,6 +166,8 @@ class OAuthSource(NonCreatableType, Source):
|
||||
class GitHubOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using GitHub.com or a GitHub-Enterprise Instance."""
|
||||
|
||||
default_icon_name = "github"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("GitHub OAuth Source")
|
||||
@@ -173,6 +177,8 @@ class GitHubOAuthSource(CreatableType, OAuthSource):
|
||||
class GitLabOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using GitLab.com or a GitLab Instance."""
|
||||
|
||||
default_icon_name = "gitlab"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("GitLab OAuth Source")
|
||||
@@ -182,6 +188,8 @@ class GitLabOAuthSource(CreatableType, OAuthSource):
|
||||
class TwitchOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Twitch."""
|
||||
|
||||
default_icon_name = "twitch"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Twitch OAuth Source")
|
||||
@@ -191,6 +199,8 @@ class TwitchOAuthSource(CreatableType, OAuthSource):
|
||||
class MailcowOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Mailcow."""
|
||||
|
||||
default_icon_name = "mailcow"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Mailcow OAuth Source")
|
||||
@@ -200,6 +210,8 @@ class MailcowOAuthSource(CreatableType, OAuthSource):
|
||||
class TwitterOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Twitter.com"""
|
||||
|
||||
default_icon_name = "twitter"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Twitter OAuth Source")
|
||||
@@ -209,6 +221,8 @@ class TwitterOAuthSource(CreatableType, OAuthSource):
|
||||
class FacebookOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Facebook.com."""
|
||||
|
||||
default_icon_name = "facebook"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Facebook OAuth Source")
|
||||
@@ -218,6 +232,8 @@ class FacebookOAuthSource(CreatableType, OAuthSource):
|
||||
class DiscordOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Discord."""
|
||||
|
||||
default_icon_name = "discord"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Discord OAuth Source")
|
||||
@@ -227,6 +243,8 @@ class DiscordOAuthSource(CreatableType, OAuthSource):
|
||||
class SlackOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Slack."""
|
||||
|
||||
default_icon_name = "slack"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Slack OAuth Source")
|
||||
@@ -236,6 +254,8 @@ class SlackOAuthSource(CreatableType, OAuthSource):
|
||||
class PatreonOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Patreon."""
|
||||
|
||||
default_icon_name = "patreon"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Patreon OAuth Source")
|
||||
@@ -245,6 +265,8 @@ class PatreonOAuthSource(CreatableType, OAuthSource):
|
||||
class GoogleOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Google or Google Workspace (GSuite)."""
|
||||
|
||||
default_icon_name = "google"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Google OAuth Source")
|
||||
@@ -254,6 +276,8 @@ class GoogleOAuthSource(CreatableType, OAuthSource):
|
||||
class AzureADOAuthSource(CreatableType, OAuthSource):
|
||||
"""(Deprecated) Social Login using Azure AD."""
|
||||
|
||||
default_icon_name = "azuread"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Azure AD OAuth Source")
|
||||
@@ -265,6 +289,8 @@ class AzureADOAuthSource(CreatableType, OAuthSource):
|
||||
class EntraIDOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Entra ID."""
|
||||
|
||||
default_icon_name = "entraid"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Entra ID OAuth Source")
|
||||
@@ -274,6 +300,8 @@ class EntraIDOAuthSource(CreatableType, OAuthSource):
|
||||
class OpenIDConnectOAuthSource(CreatableType, OAuthSource):
|
||||
"""Login using a Generic OpenID-Connect compliant provider."""
|
||||
|
||||
default_icon_name = "openidconnect"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("OpenID OAuth Source")
|
||||
@@ -283,6 +311,8 @@ class OpenIDConnectOAuthSource(CreatableType, OAuthSource):
|
||||
class AppleOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Apple."""
|
||||
|
||||
default_icon_name = "apple"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Apple OAuth Source")
|
||||
@@ -292,6 +322,8 @@ class AppleOAuthSource(CreatableType, OAuthSource):
|
||||
class OktaOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using Okta."""
|
||||
|
||||
default_icon_name = "okta"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Okta OAuth Source")
|
||||
@@ -301,6 +333,8 @@ class OktaOAuthSource(CreatableType, OAuthSource):
|
||||
class RedditOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using reddit.com."""
|
||||
|
||||
default_icon_name = "reddit"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Reddit OAuth Source")
|
||||
@@ -310,6 +344,8 @@ class RedditOAuthSource(CreatableType, OAuthSource):
|
||||
class WeChatOAuthSource(CreatableType, OAuthSource):
|
||||
"""Social Login using WeChat."""
|
||||
|
||||
default_icon_name = "wechat"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("WeChat OAuth Source")
|
||||
|
||||
@@ -5,7 +5,6 @@ from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from django.http.request import HttpRequest
|
||||
from django.templatetags.static import static
|
||||
from django.urls.base import reverse
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
@@ -46,10 +45,6 @@ class SourceType:
|
||||
AuthorizationCodeAuthMethod.BASIC_AUTH
|
||||
)
|
||||
|
||||
def icon_url(self) -> str:
|
||||
"""Get Icon URL for login"""
|
||||
return static(f"authentik/sources/{self.name}.svg")
|
||||
|
||||
def login_challenge(self, source: OAuthSource, request: HttpRequest) -> Challenge:
|
||||
"""Allow types to return custom challenges"""
|
||||
return RedirectChallenge(
|
||||
|
||||
@@ -5,7 +5,6 @@ from typing import Any
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.db import models
|
||||
from django.http.request import HttpRequest
|
||||
from django.templatetags.static import static
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.fields import CharField
|
||||
from rest_framework.serializers import BaseSerializer, Serializer
|
||||
@@ -100,12 +99,7 @@ class PlexSource(ScheduledModel, Source):
|
||||
"name": group_id,
|
||||
}
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str:
|
||||
icon = super().icon_url
|
||||
if not icon:
|
||||
icon = static("authentik/sources/plex.svg")
|
||||
return icon
|
||||
default_icon_name = "plex"
|
||||
|
||||
def ui_login_button(self, request: HttpRequest) -> UILoginButton:
|
||||
return UILoginButton(
|
||||
@@ -116,7 +110,7 @@ class PlexSource(ScheduledModel, Source):
|
||||
"slug": self.slug,
|
||||
}
|
||||
),
|
||||
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
|
||||
icon_url=self.icon_dynamic_url,
|
||||
name=self.name,
|
||||
promoted=self.promoted,
|
||||
)
|
||||
@@ -127,7 +121,7 @@ class PlexSource(ScheduledModel, Source):
|
||||
"title": self.name,
|
||||
"component": "ak-user-settings-source-plex",
|
||||
"configure_url": self.client_id,
|
||||
"icon_url": self.icon_url,
|
||||
"icon_url": self.icon_dynamic_url,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ from typing import Any
|
||||
|
||||
from django.db import models
|
||||
from django.http import HttpRequest
|
||||
from django.templatetags.static import static
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from lxml.etree import _Element # nosec
|
||||
@@ -266,12 +265,7 @@ class SAMLSource(Source):
|
||||
reverse(f"authentik_sources_saml:{view}", kwargs={"source_slug": self.slug})
|
||||
)
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str:
|
||||
icon = super().icon_url
|
||||
if not icon:
|
||||
return static("authentik/sources/saml.png")
|
||||
return icon
|
||||
default_icon_name = "saml"
|
||||
|
||||
def ui_login_button(self, request: HttpRequest) -> UILoginButton:
|
||||
return UILoginButton(
|
||||
@@ -284,7 +278,7 @@ class SAMLSource(Source):
|
||||
}
|
||||
),
|
||||
name=self.name,
|
||||
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
|
||||
icon_url=self.icon_dynamic_url,
|
||||
promoted=self.promoted,
|
||||
)
|
||||
|
||||
@@ -298,6 +292,7 @@ class SAMLSource(Source):
|
||||
kwargs={"source_slug": self.slug},
|
||||
),
|
||||
"icon_url": self.icon_url,
|
||||
"icon_themed_urls": self.icon_themed_urls,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
from django.db import models
|
||||
from django.templatetags.static import static
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.serializers import BaseSerializer, Serializer
|
||||
|
||||
@@ -27,9 +26,7 @@ class SCIMSource(Source):
|
||||
"""Return component used to edit this object"""
|
||||
return "ak-source-scim-form"
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str:
|
||||
return static("authentik/sources/scim.png")
|
||||
default_icon_name = "scim"
|
||||
|
||||
@property
|
||||
def serializer(self) -> BaseSerializer:
|
||||
|
||||
@@ -5,7 +5,6 @@ from urllib.parse import urlencode
|
||||
|
||||
from django.db import models
|
||||
from django.http import HttpRequest
|
||||
from django.templatetags.static import static
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.serializers import BaseSerializer, Serializer
|
||||
@@ -42,12 +41,7 @@ class TelegramSource(Source):
|
||||
def component(self) -> str:
|
||||
return "ak-source-telegram-form"
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str | None:
|
||||
icon = super().icon_url
|
||||
if not icon:
|
||||
icon = static("authentik/sources/telegram.svg")
|
||||
return icon
|
||||
default_icon_name = "telegram"
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[BaseSerializer]:
|
||||
@@ -66,7 +60,7 @@ class TelegramSource(Source):
|
||||
}
|
||||
),
|
||||
name=self.name,
|
||||
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
|
||||
icon_url=self.icon_dynamic_url,
|
||||
promoted=self.promoted,
|
||||
)
|
||||
|
||||
@@ -75,7 +69,7 @@ class TelegramSource(Source):
|
||||
data={
|
||||
"title": self.name,
|
||||
"component": "ak-user-settings-source-telegram",
|
||||
"icon_url": self.icon_url,
|
||||
"icon_url": self.icon_dynamic_url,
|
||||
"configure_url": urlencode(
|
||||
{
|
||||
"bot_username": self.bot_username,
|
||||
|
||||
@@ -14,7 +14,7 @@ from rest_framework.fields import BooleanField, CharField, ChoiceField, DictFiel
|
||||
from rest_framework.serializers import ValidationError
|
||||
from sentry_sdk import start_span
|
||||
|
||||
from authentik.core.api.utils import JSONDictField, PassiveSerializer
|
||||
from authentik.core.api.utils import JSONDictField, PassiveSerializer, ThemedUrlsSerializer
|
||||
from authentik.core.models import Application, Source, User
|
||||
from authentik.endpoints.connectors.agent.stage import PLAN_CONTEXT_DEVICE_AUTH_TOKEN
|
||||
from authentik.endpoints.models import Device
|
||||
@@ -85,6 +85,7 @@ class LoginSourceSerializer(PassiveSerializer):
|
||||
|
||||
name = CharField()
|
||||
icon_url = CharField(required=False, allow_null=True)
|
||||
icon_themed_urls = ThemedUrlsSerializer(required=False, allow_null=True)
|
||||
promoted = BooleanField(default=False)
|
||||
|
||||
challenge = ChallengeDictWrapper()
|
||||
|
||||
@@ -206,7 +206,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
@@ -242,7 +243,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
@@ -317,7 +319,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
@@ -373,7 +376,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
@@ -436,7 +440,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
@@ -481,7 +486,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
primary_action="Log in",
|
||||
sources=[
|
||||
{
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
@@ -523,7 +529,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
@@ -551,7 +558,8 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"component": "xak-flow-redirect",
|
||||
"to": f"/source/oauth/login/{self.source.slug}/",
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"icon_url": None,
|
||||
"icon_themed_urls": None,
|
||||
"name": self.source.name,
|
||||
"promoted": False,
|
||||
}
|
||||
|
||||
33
schema.yml
@@ -40860,6 +40860,9 @@ components:
|
||||
type: string
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -41550,6 +41553,9 @@ components:
|
||||
type: string
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -42353,6 +42359,10 @@ components:
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ThemedUrls'
|
||||
nullable: true
|
||||
promoted:
|
||||
type: boolean
|
||||
default: false
|
||||
@@ -43755,6 +43765,8 @@ components:
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -51112,6 +51124,9 @@ components:
|
||||
type: string
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -53781,6 +53796,9 @@ components:
|
||||
type: string
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -55436,7 +55454,8 @@ components:
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -56118,6 +56137,8 @@ components:
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Get the URL to the source icon. Only returns user-configured
|
||||
icons.
|
||||
readOnly: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
@@ -56580,6 +56601,11 @@ components:
|
||||
type: string
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ThemedUrls'
|
||||
nullable: true
|
||||
requires_enterprise:
|
||||
type: boolean
|
||||
default: false
|
||||
@@ -57609,6 +57635,11 @@ components:
|
||||
type: string
|
||||
icon_url:
|
||||
type: string
|
||||
nullable: true
|
||||
icon_themed_urls:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ThemedUrls'
|
||||
nullable: true
|
||||
required:
|
||||
- component
|
||||
- object_uid
|
||||
|
||||
3
web/authentik/sources/apple/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516s1.52.087 2.475-1.258.762-2.391.728-2.43m3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422s1.675-2.789 1.698-2.854-.597-.79-1.254-1.157a3.7 3.7 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56s.625 1.924 1.273 2.796c.576.984 1.34 1.667 1.659 1.899s1.219.386 1.843.067c.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758q.52-1.185.473-1.282"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 756 B |
3
web/authentik/sources/apple/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516s1.52.087 2.475-1.258.762-2.391.728-2.43m3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422s1.675-2.789 1.698-2.854-.597-.79-1.254-1.157a3.7 3.7 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56s.625 1.924 1.273 2.796c.576.984 1.34 1.667 1.659 1.899s1.219.386 1.843.067c.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758q.52-1.185.473-1.282"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 761 B |
3
web/authentik/sources/azuread/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 208 B |
3
web/authentik/sources/azuread/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 213 B |
3
web/authentik/sources/discord/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M13.545 2.907a13.2 13.2 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.2 12.2 0 0 0-3.658 0 8 8 0 0 0-.412-.833.05.05 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.04.04 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032q.003.022.021.037a13.3 13.3 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019q.463-.63.818-1.329a.05.05 0 0 0-.01-.059l-.018-.011a9 9 0 0 1-1.248-.595.05.05 0 0 1-.02-.066l.015-.019q.127-.095.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.05.05 0 0 1 .053.007q.121.1.248.195a.05.05 0 0 1-.004.085 8 8 0 0 1-1.249.594.05.05 0 0 0-.03.03.05.05 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.2 13.2 0 0 0 4.001-2.02.05.05 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.03.03 0 0 0-.02-.019m-8.198 7.307c-.789 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612m5.316 0c-.788 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
web/authentik/sources/discord/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M13.545 2.907a13.2 13.2 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.2 12.2 0 0 0-3.658 0 8 8 0 0 0-.412-.833.05.05 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.04.04 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032q.003.022.021.037a13.3 13.3 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019q.463-.63.818-1.329a.05.05 0 0 0-.01-.059l-.018-.011a9 9 0 0 1-1.248-.595.05.05 0 0 1-.02-.066l.015-.019q.127-.095.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.05.05 0 0 1 .053.007q.121.1.248.195a.05.05 0 0 1-.004.085 8 8 0 0 1-1.249.594.05.05 0 0 0-.03.03.05.05 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.2 13.2 0 0 0 4.001-2.02.05.05 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.03.03 0 0 0-.02-.019m-8.198 7.307c-.789 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612m5.316 0c-.788 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
web/authentik/sources/dropbox/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M8.01 4.555 4.005 7.11 8.01 9.665 4.005 12.22 0 9.651l4.005-2.555L0 4.555 4.005 2zm-4.026 8.487 4.006-2.555 4.005 2.555-4.005 2.555zm4.026-3.39 4.005-2.556L8.01 4.555 11.995 2 16 4.555 11.995 7.11 16 9.665l-4.005 2.555z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 340 B |
3
web/authentik/sources/dropbox/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M8.01 4.555 4.005 7.11 8.01 9.665 4.005 12.22 0 9.651l4.005-2.555L0 4.555 4.005 2zm-4.026 8.487 4.006-2.555 4.005 2.555-4.005 2.555zm4.026-3.39 4.005-2.556L8.01 4.555 11.995 2 16 4.555 11.995 7.11 16 9.665l-4.005 2.555z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 345 B |
3
web/authentik/sources/entraid/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 208 B |
3
web/authentik/sources/entraid/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 213 B |
3
web/authentik/sources/facebook/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 408 B |
3
web/authentik/sources/facebook/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 413 B |
3
web/authentik/sources/github/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 683 B |
3
web/authentik/sources/github/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 688 B |
3
web/authentik/sources/gitlab/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="m15.734 6.1-.022-.058L13.534.358a.57.57 0 0 0-.563-.356.6.6 0 0 0-.328.122.6.6 0 0 0-.193.294l-1.47 4.499H5.025l-1.47-4.5A.572.572 0 0 0 2.47.358L.289 6.04l-.022.057A4.044 4.044 0 0 0 1.61 10.77l.007.006.02.014 3.318 2.485 1.64 1.242 1 .755a.67.67 0 0 0 .814 0l1-.755 1.64-1.242 3.338-2.5.009-.007a4.05 4.05 0 0 0 1.34-4.668Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 446 B |
3
web/authentik/sources/gitlab/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="m15.734 6.1-.022-.058L13.534.358a.57.57 0 0 0-.563-.356.6.6 0 0 0-.328.122.6.6 0 0 0-.193.294l-1.47 4.499H5.025l-1.47-4.5A.572.572 0 0 0 2.47.358L.289 6.04l-.022.057A4.044 4.044 0 0 0 1.61 10.77l.007.006.02.014 3.318 2.485 1.64 1.242 1 .755a.67.67 0 0 0 .814 0l1-.755 1.64-1.242 3.338-2.5.009-.007a4.05 4.05 0 0 0 1.34-4.668Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
3
web/authentik/sources/google/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M15.545 6.558a9.4 9.4 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.7 7.7 0 0 1 5.352 2.082l-2.284 2.284A4.35 4.35 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.8 4.8 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.7 3.7 0 0 0 1.599-2.431H8v-3.08z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 465 B |
3
web/authentik/sources/google/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M15.545 6.558a9.4 9.4 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.7 7.7 0 0 1 5.352 2.082l-2.284 2.284A4.35 4.35 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.8 4.8 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.7 3.7 0 0 0 1.599-2.431H8v-3.08z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 470 B |
4
web/authentik/sources/reddit/dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z"/>
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 959 B |
4
web/authentik/sources/reddit/light.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z"/>
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 964 B |
5
web/authentik/sources/saml/dark.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#ffffff">
|
||||
<path d="M7.754 2l.463.41c.343.304.687.607 1.026.915C11.44 5.32 13.3 7.565 14.7 10.149c.072.132.137.268.202.403l.098.203-.108.057-.081-.115-.21-.299-.147-.214c-1.019-1.479-2.04-2.96-3.442-4.145a6.563 6.563 0 00-1.393-.904c-1.014-.485-1.916-.291-2.69.505-.736.757-1.118 1.697-1.463 2.653-.045.123-.092.245-.139.367l-.082.215-.172-.055c.1-.348.192-.698.284-1.049.21-.795.42-1.59.712-2.356.31-.816.702-1.603 1.093-2.39.169-.341.338-.682.5-1.025h.092z"/>
|
||||
<path d="M8.448 11.822c-1.626.77-5.56 1.564-7.426 1.36C.717 11.576 3.71 4.05 5.18 2.91l-.095.218a4.638 4.638 0 01-.138.303l-.066.129c-.76 1.462-1.519 2.926-1.908 4.53a7.482 7.482 0 00-.228 1.689c-.01 1.34.824 2.252 2.217 2.309.67.027 1.347-.043 2.023-.114.294-.03.587-.061.88-.084.108-.008.214-.021.352-.039l.231-.028z"/>
|
||||
<path d="M3.825 14.781c-.445.034-.89.068-1.333.108 4.097.39 8.03-.277 11.91-1.644-1.265-2.23-2.97-3.991-4.952-5.522.026.098.084.169.141.239l.048.06c.17.226.348.448.527.67.409.509.818 1.018 1.126 1.578.778 1.42.356 2.648-1.168 3.296-1.002.427-2.097.718-3.18.892-1.03.164-2.075.243-3.119.323z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
5
web/authentik/sources/saml/light.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
|
||||
<path d="M7.754 2l.463.41c.343.304.687.607 1.026.915C11.44 5.32 13.3 7.565 14.7 10.149c.072.132.137.268.202.403l.098.203-.108.057-.081-.115-.21-.299-.147-.214c-1.019-1.479-2.04-2.96-3.442-4.145a6.563 6.563 0 00-1.393-.904c-1.014-.485-1.916-.291-2.69.505-.736.757-1.118 1.697-1.463 2.653-.045.123-.092.245-.139.367l-.082.215-.172-.055c.1-.348.192-.698.284-1.049.21-.795.42-1.59.712-2.356.31-.816.702-1.603 1.093-2.39.169-.341.338-.682.5-1.025h.092z"/>
|
||||
<path d="M8.448 11.822c-1.626.77-5.56 1.564-7.426 1.36C.717 11.576 3.71 4.05 5.18 2.91l-.095.218a4.638 4.638 0 01-.138.303l-.066.129c-.76 1.462-1.519 2.926-1.908 4.53a7.482 7.482 0 00-.228 1.689c-.01 1.34.824 2.252 2.217 2.309.67.027 1.347-.043 2.023-.114.294-.03.587-.061.88-.084.108-.008.214-.021.352-.039l.231-.028z"/>
|
||||
<path d="M3.825 14.781c-.445.034-.89.068-1.333.108 4.097.39 8.03-.277 11.91-1.644-1.265-2.23-2.97-3.991-4.952-5.522.026.098.084.169.141.239l.048.06c.17.226.348.448.527.67.409.509.818 1.018 1.126 1.578.778 1.42.356 2.648-1.168 3.296-1.002.427-2.097.718-3.18.892-1.03.164-2.075.243-3.119.323z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
6
web/authentik/sources/scim/dark.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="750" height="250" viewBox="0 0 7496 2500" fill="#ffffff">
|
||||
<path d="M725 2489c-310-45-554-253-619-529-21-86-21-313-1-398 31-129 112-250 219-326 118-85 226-127 615-241 216-63 327-126 351-201 7-20 10-64 8-99-3-50-10-70-32-100-57-74-149-108-296-108-207 0-385 68-595 228l-82 63-142-179c-78-99-144-186-147-193-6-16 106-111 211-178 357-230 868-280 1199-119 264 128 397 370 384 696-9 226-84 370-253 490-118 84-225 128-540 221-241 72-330 110-375 160-82 94-54 250 55 311 22 12 71 27 110 34 169 29 380-37 610-190 33-22 63-37 67-33 4 4 63 94 133 200l125 194-22 19c-59 49-194 133-272 169-212 98-491 141-711 109z"/>
|
||||
<path d="M3032 2490c-392-55-719-296-892-656-86-179-119-320-127-539-4-124-2-185 12-269 85-546 481-947 1002-1017 108-14 330-7 430 15 94 20 215 67 280 108l52 33-131 202-130 202-37-19c-101-51-278-72-409-47-132 25-221 74-322 176-131 131-197 279-221 490-26 226 52 473 197 630 81 88 156 137 264 175 75 26 98 30 195 30 117-1 159-9 268-51 37-14 69-24 71-22 2 2 61 91 130 198l127 194-23 25c-36 39-180 102-282 123-105 22-357 33-454 19z"/>
|
||||
<path d="M4120 1250V0h137c221 0 299 35 362 162 27 52 31 72 31 138 0 42-5 103-12 135-11 57-11 59 14 80 53 46 60 84 22 122-14 14-24 26-22 27 105 63 112 80 73 175-44 109-25 153 93 216 91 48 127 139 83 210-10 17-63 91-117 165-198 269-200 274-138 395 32 64 35 75 30 130-3 35-30 131-64 230-63 184-74 208-121 273l-31 42h-170V1250z"/>
|
||||
<path d="M5210 1250V0h250l250 1 2 819 3 820 314-505c173-277 319-504 325-504s27 27 46 59c19 32 161 261 315 509l280 450 3-824 2-824h250l250 1v2499h-273l-272-1-213-362c-350-595-371-631-381-641-11-11 18-59-322 521l-283 482h-273l-273-1V1250z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
6
web/authentik/sources/scim/light.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="750" height="250" viewBox="0 0 7496 2500" fill="currentColor">
|
||||
<path d="M725 2489c-310-45-554-253-619-529-21-86-21-313-1-398 31-129 112-250 219-326 118-85 226-127 615-241 216-63 327-126 351-201 7-20 10-64 8-99-3-50-10-70-32-100-57-74-149-108-296-108-207 0-385 68-595 228l-82 63-142-179c-78-99-144-186-147-193-6-16 106-111 211-178 357-230 868-280 1199-119 264 128 397 370 384 696-9 226-84 370-253 490-118 84-225 128-540 221-241 72-330 110-375 160-82 94-54 250 55 311 22 12 71 27 110 34 169 29 380-37 610-190 33-22 63-37 67-33 4 4 63 94 133 200l125 194-22 19c-59 49-194 133-272 169-212 98-491 141-711 109z"/>
|
||||
<path d="M3032 2490c-392-55-719-296-892-656-86-179-119-320-127-539-4-124-2-185 12-269 85-546 481-947 1002-1017 108-14 330-7 430 15 94 20 215 67 280 108l52 33-131 202-130 202-37-19c-101-51-278-72-409-47-132 25-221 74-322 176-131 131-197 279-221 490-26 226 52 473 197 630 81 88 156 137 264 175 75 26 98 30 195 30 117-1 159-9 268-51 37-14 69-24 71-22 2 2 61 91 130 198l127 194-23 25c-36 39-180 102-282 123-105 22-357 33-454 19z"/>
|
||||
<path d="M4120 1250V0h137c221 0 299 35 362 162 27 52 31 72 31 138 0 42-5 103-12 135-11 57-11 59 14 80 53 46 60 84 22 122-14 14-24 26-22 27 105 63 112 80 73 175-44 109-25 153 93 216 91 48 127 139 83 210-10 17-63 91-117 165-198 269-200 274-138 395 32 64 35 75 30 130-3 35-30 131-64 230-63 184-74 208-121 273l-31 42h-170V1250z"/>
|
||||
<path d="M5210 1250V0h250l250 1 2 819 3 820 314-505c173-277 319-504 325-504s27 27 46 59c19 32 161 261 315 509l280 450 3-824 2-824h250l250 1v2499h-273l-272-1-213-362c-350-595-371-631-381-641-11-11 18-59-322 521l-283 482h-273l-273-1V1250z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
3
web/authentik/sources/slack/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036 0 10.111.756 8.43 1.68 8.43h1.682zm.846 0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685 0 0 1-1.682-1.68zM5.89 3.362c-.926 0-1.682-.756-1.682-1.681S4.964 0 5.89 0s1.68.756 1.68 1.68v1.682zm0 .846c.924 0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57 0 6.814 0 5.89c0-.926.756-1.682 1.68-1.682zm6.749 1.682c0-.926.755-1.682 1.68-1.682S16 4.964 16 5.889s-.756 1.681-1.68 1.681h-1.681zm-.848 0c0 .924-.755 1.68-1.68 1.68A1.685 1.685 0 0 1 8.43 5.89V1.68C8.43.757 9.186 0 10.11 0c.926 0 1.681.756 1.681 1.68zm-1.681 6.748c.926 0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924 0-1.68-.755-1.68-1.68s.756-1.681 1.68-1.681h4.21c.924 0 1.68.756 1.68 1.68 0 .926-.756 1.681-1.68 1.681z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 947 B |
3
web/authentik/sources/slack/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036 0 10.111.756 8.43 1.68 8.43h1.682zm.846 0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685 0 0 1-1.682-1.68zM5.89 3.362c-.926 0-1.682-.756-1.682-1.681S4.964 0 5.89 0s1.68.756 1.68 1.68v1.682zm0 .846c.924 0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57 0 6.814 0 5.89c0-.926.756-1.682 1.68-1.682zm6.749 1.682c0-.926.755-1.682 1.68-1.682S16 4.964 16 5.889s-.756 1.681-1.68 1.681h-1.681zm-.848 0c0 .924-.755 1.68-1.68 1.68A1.685 1.685 0 0 1 8.43 5.89V1.68C8.43.757 9.186 0 10.11 0c.926 0 1.681.756 1.681 1.68zm-1.681 6.748c.926 0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924 0-1.68-.755-1.68-1.68s.756-1.681 1.68-1.681h4.21c.924 0 1.68.756 1.68 1.68 0 .926-.756 1.681-1.68 1.681z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 952 B |
3
web/authentik/sources/telegram/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.287 5.906q-1.168.486-4.666 2.01-.567.225-.595.442c-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294q.39.01.868-.32 3.269-2.206 3.374-2.23c.05-.012.12-.026.166.016s.042.12.037.141c-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8 8 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629q.14.092.27.187c.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.4 1.4 0 0 0-.013-.315.34.34 0 0 0-.114-.217.53.53 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 684 B |
3
web/authentik/sources/telegram/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.287 5.906q-1.168.486-4.666 2.01-.567.225-.595.442c-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294q.39.01.868-.32 3.269-2.206 3.374-2.23c.05-.012.12-.026.166.016s.042.12.037.141c-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8 8 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629q.14.092.27.187c.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.4 1.4 0 0 0-.013-.315.34.34 0 0 0-.114-.217.53.53 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 689 B |
4
web/authentik/sources/twitch/dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
|
||||
<path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 309 B |
4
web/authentik/sources/twitch/light.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
|
||||
<path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 314 B |
3
web/authentik/sources/twitter/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 273 B |
3
web/authentik/sources/twitter/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 278 B |
4
web/authentik/sources/wechat/dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M11.176 14.429c-2.665 0-4.826-1.8-4.826-4.018 0-2.22 2.159-4.02 4.824-4.02S16 8.191 16 10.411c0 1.21-.65 2.301-1.666 3.036a.32.32 0 0 0-.12.366l.218.81a.6.6 0 0 1 .029.117.166.166 0 0 1-.162.162.2.2 0 0 1-.092-.03l-1.057-.61a.5.5 0 0 0-.256-.074.5.5 0 0 0-.142.021 5.7 5.7 0 0 1-1.576.22M9.064 9.542a.647.647 0 1 0 .557-1 .645.645 0 0 0-.646.647.6.6 0 0 0 .09.353Zm3.232.001a.646.646 0 1 0 .546-1 .645.645 0 0 0-.644.644.63.63 0 0 0 .098.356"/>
|
||||
<path d="M0 6.826c0 1.455.781 2.765 2.001 3.656a.385.385 0 0 1 .143.439l-.161.6-.1.373a.5.5 0 0 0-.032.14.19.19 0 0 0 .193.193q.06 0 .111-.029l1.268-.733a.6.6 0 0 1 .308-.088q.088 0 .171.025a6.8 6.8 0 0 0 1.625.26 4.5 4.5 0 0 1-.177-1.251c0-2.936 2.785-5.02 5.824-5.02l.15.002C10.587 3.429 8.392 2 5.796 2 2.596 2 0 4.16 0 6.826m4.632-1.555a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0m3.875 0a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 996 B |
4
web/authentik/sources/wechat/light.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M11.176 14.429c-2.665 0-4.826-1.8-4.826-4.018 0-2.22 2.159-4.02 4.824-4.02S16 8.191 16 10.411c0 1.21-.65 2.301-1.666 3.036a.32.32 0 0 0-.12.366l.218.81a.6.6 0 0 1 .029.117.166.166 0 0 1-.162.162.2.2 0 0 1-.092-.03l-1.057-.61a.5.5 0 0 0-.256-.074.5.5 0 0 0-.142.021 5.7 5.7 0 0 1-1.576.22M9.064 9.542a.647.647 0 1 0 .557-1 .645.645 0 0 0-.646.647.6.6 0 0 0 .09.353Zm3.232.001a.646.646 0 1 0 .546-1 .645.645 0 0 0-.644.644.63.63 0 0 0 .098.356"/>
|
||||
<path d="M0 6.826c0 1.455.781 2.765 2.001 3.656a.385.385 0 0 1 .143.439l-.161.6-.1.373a.5.5 0 0 0-.032.14.19.19 0 0 0 .193.193q.06 0 .111-.029l1.268-.733a.6.6 0 0 1 .308-.088q.088 0 .171.025a6.8 6.8 0 0 0 1.625.26 4.5 4.5 0 0 1-.177-1.251c0-2.936 2.785-5.02 5.824-5.02l.15.002C10.587 3.429 8.392 2 5.796 2 2.596 2 0 4.16 0 6.826m4.632-1.555a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0m3.875 0a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1001 B |
3
web/authentik/sources/wsfed/dark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
|
||||
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 208 B |
3
web/authentik/sources/wsfed/light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 213 B |
@@ -1,21 +1,41 @@
|
||||
import { PolicyBindingCheckTarget } from "#common/policies/utils";
|
||||
import { ResolvedUITheme } from "#common/theme";
|
||||
|
||||
import { ThemedUrls } from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { html, TemplateResult } from "lit";
|
||||
|
||||
export function renderSourceIcon(name: string, iconUrl: string | undefined | null): TemplateResult {
|
||||
function resolveSourceIconUrl(
|
||||
iconUrl: string | undefined | null,
|
||||
iconThemedUrls: ThemedUrls | undefined | null,
|
||||
theme: ResolvedUITheme | undefined,
|
||||
): string | undefined | null {
|
||||
if (theme && iconThemedUrls?.[theme]) {
|
||||
return iconThemedUrls[theme];
|
||||
}
|
||||
return iconUrl;
|
||||
}
|
||||
|
||||
export function renderSourceIcon(
|
||||
name: string,
|
||||
iconUrl: string | undefined | null,
|
||||
iconThemedUrls?: ThemedUrls | null,
|
||||
theme?: ResolvedUITheme,
|
||||
): TemplateResult {
|
||||
const resolvedIconUrl = resolveSourceIconUrl(iconUrl, iconThemedUrls, theme);
|
||||
const icon = html`<i
|
||||
part="source-icon"
|
||||
role="img"
|
||||
class="fas fa-share-square"
|
||||
title="${name}"
|
||||
></i>`;
|
||||
if (iconUrl) {
|
||||
if (iconUrl.startsWith("fa://")) {
|
||||
const url = iconUrl.replaceAll("fa://", "");
|
||||
if (resolvedIconUrl) {
|
||||
if (resolvedIconUrl.startsWith("fa://")) {
|
||||
const url = resolvedIconUrl.replaceAll("fa://", "");
|
||||
return html`<i part="source-icon" role="img" class="fas ${url}" title="${name}"></i>`;
|
||||
}
|
||||
return html`<img part="source-icon" src="${iconUrl}" alt="${name}" />`;
|
||||
return html`<img part="source-icon" src="${resolvedIconUrl}" alt="${name}" />`;
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
padding-inline-start: 0;
|
||||
border-top-color: var(--ak-dark-background-lighter);
|
||||
|
||||
.pf-c-data-list__cell img {
|
||||
.pf-c-data-list__cell i[part="source-icon"] {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ export class UserSourceSettingsPage extends AKElement {
|
||||
const connection = this.sourceToConnection.get(source);
|
||||
const connectionPk = connection?.pk ?? -1;
|
||||
const connectionUserPk = connection?.user ?? -1;
|
||||
|
||||
return html`<li
|
||||
class="pf-c-data-list__item"
|
||||
part="list-item"
|
||||
@@ -159,7 +158,13 @@ export class UserSourceSettingsPage extends AKElement {
|
||||
<div class="pf-c-data-list__item-row">
|
||||
<div class="pf-c-data-list__item-content">
|
||||
<div class="pf-c-data-list__cell">
|
||||
${renderSourceIcon(source.title, source.iconUrl)} ${source.title}
|
||||
${renderSourceIcon(
|
||||
source.title,
|
||||
source.iconUrl,
|
||||
source.iconThemedUrls,
|
||||
this.activeTheme,
|
||||
)}
|
||||
${source.title}
|
||||
</div>
|
||||
<div class="pf-c-data-list__cell">${this.renderSourceSettings(source)}</div>
|
||||
</div>
|
||||
|
||||
@@ -4,12 +4,13 @@ import "#elements/Alert";
|
||||
import { WithLicenseSummary } from "#elements/mixins/license";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
import { ifPresent } from "#elements/utils/attributes";
|
||||
import { renderDynamicIcon } from "#elements/utils/images";
|
||||
import { WizardPage } from "#elements/wizard/WizardPage";
|
||||
|
||||
import { TypeCreate } from "@goauthentik/api";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { css, CSSResult, html } from "lit";
|
||||
import { css, CSSResult, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { classMap } from "lit/directives/class-map.js";
|
||||
import { guard } from "lit/directives/guard.js";
|
||||
@@ -57,8 +58,9 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
|
||||
max-height: 2em;
|
||||
min-height: 2em;
|
||||
}
|
||||
:host([theme="dark"]) .pf-c-card__header-main img {
|
||||
filter: invert(1);
|
||||
.pf-c-card__header-main .font-awesome {
|
||||
font-size: 2em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
:host([theme="dark"]) .pf-c-card {
|
||||
@@ -114,9 +116,14 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
|
||||
|
||||
return this.types.map((type, idx) => {
|
||||
const disabled = !!(type.requiresEnterprise && !this.hasEnterpriseLicense);
|
||||
|
||||
const selected = this.selectedType === type;
|
||||
const inputID = `${type.component}-${type.modelName}`;
|
||||
const icon = renderDynamicIcon({
|
||||
urls: type.iconUrl,
|
||||
theme: this.activeTheme,
|
||||
alt: msg(str`${type.name} Icon`),
|
||||
ariaHidden: true,
|
||||
});
|
||||
|
||||
return html`<div
|
||||
class=${classMap({
|
||||
@@ -139,21 +146,15 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
|
||||
@click=${() => {
|
||||
if (disabled) return;
|
||||
|
||||
this.selectedType = type;
|
||||
this.#selectDispatch(type);
|
||||
}}
|
||||
this.selectedType = type;
|
||||
this.#selectDispatch(type);
|
||||
}}
|
||||
>
|
||||
${type.iconUrl
|
||||
${icon !== nothing
|
||||
? html`<div role="presentation" class="pf-c-card__header">
|
||||
<div role="presentation" class="pf-c-card__header-main">
|
||||
<img
|
||||
aria-hidden="true"
|
||||
src=${type.iconUrl}
|
||||
alt=${msg(str`${type.name} Icon`)}
|
||||
/>
|
||||
</div>
|
||||
<div role="presentation" class="pf-c-card__header-main">${icon}</div>
|
||||
</div>`
|
||||
: null}
|
||||
: nothing}
|
||||
<div role="heading" aria-level="2" class="pf-c-card__title">${type.name}</div>
|
||||
<div class="pf-c-card__body" id=${`${inputID}-description`}>
|
||||
${type.description}
|
||||
@@ -162,7 +163,7 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
|
||||
? html`<div class="pf-c-card__footer">
|
||||
<ak-license-notice></ak-license-notice>
|
||||
</div> `
|
||||
: null}
|
||||
: nothing}
|
||||
</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -79,7 +79,10 @@ export const ChallengeEverything = flowFactory("ak-stage-identification", {
|
||||
component: "xak-flow-redirect",
|
||||
to: "foo",
|
||||
},
|
||||
iconUrl: "/static/authentik/sources/google.svg",
|
||||
iconThemedUrls: {
|
||||
light: "/static/authentik/sources/google/light.svg",
|
||||
dark: "/static/authentik/sources/google/dark.svg",
|
||||
},
|
||||
},
|
||||
],
|
||||
recoveryUrl: "foo",
|
||||
|
||||
@@ -333,9 +333,9 @@ export class IdentificationStage extends BaseStage<
|
||||
|
||||
//#region Render
|
||||
protected renderDefaultSource(source: LoginSource, showLabels: boolean) {
|
||||
const { name, iconUrl, challenge } = source;
|
||||
const { name, iconUrl, iconThemedUrls, challenge } = source;
|
||||
|
||||
const icon = renderSourceIcon(name, iconUrl);
|
||||
const icon = renderSourceIcon(name, iconUrl, iconThemedUrls, this.activeTheme);
|
||||
return html`<button
|
||||
type="button"
|
||||
@click=${() => this.#dispatchChallengeToHost(challenge)}
|
||||
|
||||
@@ -66,10 +66,7 @@ ak-stage-identification.style-scope fieldset[name="login-sources"] {
|
||||
|
||||
:host([theme="dark"]),
|
||||
ak-stage-identification[theme="dark"].style-scope {
|
||||
fieldset[name="login-sources"] .pf-c-button__icon {
|
||||
img,
|
||||
.pf-c-button__icon .fas {
|
||||
filter: invert(1);
|
||||
}
|
||||
fieldset[name="login-sources"] .pf-c-button__icon i[part="source-icon"] {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
|
||||