Merge branch 'main' into application-wizard-2
* main: (36 commits) website/blog: add github user name links (#6468) website/developer-docs: add new template for procedures (#6390) website/blogs: blog to celebrate hackathon (#6457) web/flows: add more stories (#6444) web: bump prettier from 3.0.0 to 3.0.1 in /web (#6465) core: bump debugpy from 1.6.7 to 1.6.8 (#6458) ci: bump peter-evans/create-pull-request from 4 to 5 (#6459) web: bump lit from 2.7.6 to 2.8.0 in /web (#6460) web: bump @fortawesome/fontawesome-free from 6.4.0 to 6.4.2 in /web (#6461) web: bump chart.js from 4.3.2 to 4.3.3 in /web (#6462) web: bump @lit-labs/task from 2.1.2 to 3.0.0 in /web (#6463) web, website: compress images (#6121) core: bump cryptography from 41.0.2 to 41.0.3 (#6456) root: replace builtin psycopg libpq binary implementation with distro… (#6448) website: fix broken links in NewsBar core: bump github.com/getsentry/sentry-go from 0.22.0 to 0.23.0 (#6449) core: bump goauthentik.io/api/v3 from 3.2023061.6 to 3.2023061.7 (#6450) web: bump pyright from 1.1.319 to 1.1.320 in /web (#6451) core: bump ruff from 0.0.281 to 0.0.282 (#6453) core: bump golang from 1.20.6-bullseye to 1.20.7-bullseye (#6454) ...
|
@ -14,7 +14,7 @@ runs:
|
|||
run: |
|
||||
pipx install poetry || true
|
||||
sudo apt update
|
||||
sudo apt install -y libxmlsec1-dev pkg-config gettext
|
||||
sudo apt install -y libpq-dev openssl libxmlsec1-dev pkg-config gettext
|
||||
- name: Setup python and restore poetry
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
|
|
|
@ -38,6 +38,11 @@ updates:
|
|||
patterns:
|
||||
- "@babel/*"
|
||||
- "babel-*"
|
||||
eslint:
|
||||
patterns:
|
||||
- "@typescript-eslint/eslint-*"
|
||||
- "eslint"
|
||||
- "eslint-*"
|
||||
storybook:
|
||||
patterns:
|
||||
- "@storybook/*"
|
||||
|
|
|
@ -88,8 +88,8 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
psql:
|
||||
- 11-alpine
|
||||
- 12-alpine
|
||||
- 15-alpine
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup authentik env
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
name: authentik-compress-images
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "**.jpg"
|
||||
- "**.jpeg"
|
||||
- "**.png"
|
||||
- "**.webp"
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.jpg"
|
||||
- "**.jpeg"
|
||||
- "**.png"
|
||||
- "**.webp"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
compress:
|
||||
name: compress
|
||||
runs-on: ubuntu-latest
|
||||
# Don't run on forks. Token will not be available. Will run on main and open a PR anyway
|
||||
if: |
|
||||
github.repository == 'goauthentik/authentik' &&
|
||||
(github.event_name != 'pull_request' ||
|
||||
github.event.pull_request.head.repo.full_name == github.repository)
|
||||
steps:
|
||||
- id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ secrets.GH_APP_ID }}
|
||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
- name: Compress images
|
||||
id: compress
|
||||
uses: calibreapp/image-actions@main
|
||||
with:
|
||||
githubToken: ${{ steps.generate_token.outputs.token }}
|
||||
compressOnly: ${{ github.event_name != 'pull_request' }}
|
||||
- uses: peter-evans/create-pull-request@v5
|
||||
if: "${{ github.event_name != 'pull_request' && steps.compress.outputs.markdown != '' }}"
|
||||
id: cpr
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
title: "*: Auto compress images"
|
||||
branch-suffix: timestamp
|
||||
commit-messsage: "*: compress images"
|
||||
body: ${{ steps.compress.outputs.markdown }}
|
||||
delete-branch: true
|
||||
signoff: true
|
||||
- uses: peter-evans/enable-pull-request-automerge@v3
|
||||
if: "${{ github.event_name != 'pull_request' && steps.compress.outputs.markdown != '' }}"
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
merge-method: squash
|
|
@ -31,7 +31,8 @@
|
|||
"!Format sequence",
|
||||
"!Condition sequence",
|
||||
"!Env sequence",
|
||||
"!Env scalar"
|
||||
"!Env scalar",
|
||||
"!If sequence"
|
||||
],
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||
"typescript.preferences.importModuleSpecifierEnding": "index",
|
||||
|
|
|
@ -31,7 +31,7 @@ RUN pip install --no-cache-dir poetry && \
|
|||
poetry export -f requirements.txt --dev --output requirements-dev.txt
|
||||
|
||||
# Stage 4: Build go proxy
|
||||
FROM docker.io/golang:1.20.6-bullseye AS go-builder
|
||||
FROM docker.io/golang:1.20.7-bullseye AS go-builder
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
|
@ -81,13 +81,13 @@ COPY --from=geoip /usr/share/GeoIP /geoip
|
|||
|
||||
RUN apt-get update && \
|
||||
# Required for installing pip packages
|
||||
apt-get install -y --no-install-recommends build-essential pkg-config libxmlsec1-dev zlib1g-dev && \
|
||||
apt-get install -y --no-install-recommends build-essential pkg-config libxmlsec1-dev zlib1g-dev libpq-dev python3-dev && \
|
||||
# Required for runtime
|
||||
apt-get install -y --no-install-recommends libxmlsec1-openssl libmaxminddb0 && \
|
||||
apt-get install -y --no-install-recommends libpq5 openssl libxmlsec1-openssl libmaxminddb0 && \
|
||||
# Required for bootstrap & healtcheck
|
||||
apt-get install -y --no-install-recommends runit && \
|
||||
pip install --no-cache-dir -r /requirements.txt && \
|
||||
apt-get remove --purge -y build-essential pkg-config libxmlsec1-dev && \
|
||||
apt-get remove --purge -y build-essential pkg-config libxmlsec1-dev libpq-dev python3-dev && \
|
||||
apt-get autoremove --purge -y && \
|
||||
apt-get clean && \
|
||||
rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/ && \
|
||||
|
|
3
Makefile
|
@ -140,6 +140,9 @@ web-watch:
|
|||
touch web/dist/.gitkeep
|
||||
cd web && npm run watch
|
||||
|
||||
web-storybook-watch:
|
||||
cd web && npm run storybook
|
||||
|
||||
web-lint-fix:
|
||||
cd web && npm run prettier
|
||||
|
||||
|
|
|
@ -93,10 +93,10 @@ class ConfigView(APIView):
|
|||
"traces_sample_rate": float(CONFIG.get("error_reporting.sample_rate", 0.4)),
|
||||
},
|
||||
"capabilities": self.get_capabilities(),
|
||||
"cache_timeout": int(CONFIG.get("redis.cache_timeout")),
|
||||
"cache_timeout_flows": int(CONFIG.get("redis.cache_timeout_flows")),
|
||||
"cache_timeout_policies": int(CONFIG.get("redis.cache_timeout_policies")),
|
||||
"cache_timeout_reputation": int(CONFIG.get("redis.cache_timeout_reputation")),
|
||||
"cache_timeout": CONFIG.get_int("redis.cache_timeout"),
|
||||
"cache_timeout_flows": CONFIG.get_int("redis.cache_timeout_flows"),
|
||||
"cache_timeout_policies": CONFIG.get_int("redis.cache_timeout_policies"),
|
||||
"cache_timeout_reputation": CONFIG.get_int("redis.cache_timeout_reputation"),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,5 @@ entries:
|
|||
state: absent
|
||||
- identifiers:
|
||||
name: "%(id)s"
|
||||
expression: |
|
||||
return True
|
||||
model: authentik_policies_expression.expressionpolicy
|
||||
state: absent
|
||||
|
|
|
@ -9,6 +9,8 @@ context:
|
|||
mapping:
|
||||
key1: value
|
||||
key2: 2
|
||||
context1: context-nested-value
|
||||
context2: !Context context1
|
||||
entries:
|
||||
- model: !Format ["%s", authentik_sources_oauth.oauthsource]
|
||||
state: !Format ["%s", present]
|
||||
|
@ -97,6 +99,7 @@ entries:
|
|||
[list, with, items, !Format ["foo-%s", !Context foo]],
|
||||
]
|
||||
if_true_simple: !If [!Context foo, true, text]
|
||||
if_short: !If [!Context foo]
|
||||
if_false_simple: !If [null, false, 2]
|
||||
enumerate_mapping_to_mapping: !Enumerate [
|
||||
!Context mapping,
|
||||
|
@ -141,6 +144,7 @@ entries:
|
|||
]
|
||||
]
|
||||
]
|
||||
nested_context: !Context context2
|
||||
identifiers:
|
||||
name: test
|
||||
conditions:
|
||||
|
|
|
@ -155,6 +155,7 @@ class TestBlueprintsV1(TransactionTestCase):
|
|||
},
|
||||
"if_false_complex": ["list", "with", "items", "foo-bar"],
|
||||
"if_true_simple": True,
|
||||
"if_short": True,
|
||||
"if_false_simple": 2,
|
||||
"enumerate_mapping_to_mapping": {
|
||||
"prefix-key1": "other-prefix-value",
|
||||
|
@ -211,6 +212,7 @@ class TestBlueprintsV1(TransactionTestCase):
|
|||
],
|
||||
},
|
||||
},
|
||||
"nested_context": "context-nested-value",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
|
@ -249,6 +249,8 @@ class Context(YAMLTag):
|
|||
value = self.default
|
||||
if self.key in blueprint.context:
|
||||
value = blueprint.context[self.key]
|
||||
if isinstance(value, YAMLTag):
|
||||
return value.resolve(entry, blueprint)
|
||||
return value
|
||||
|
||||
|
||||
|
@ -372,6 +374,10 @@ class If(YAMLTag):
|
|||
def __init__(self, loader: "BlueprintLoader", node: SequenceNode) -> None:
|
||||
super().__init__()
|
||||
self.condition = loader.construct_object(node.value[0])
|
||||
if len(node.value) == 1:
|
||||
self.when_true = True
|
||||
self.when_false = False
|
||||
else:
|
||||
self.when_true = loader.construct_object(node.value[1])
|
||||
self.when_false = loader.construct_object(node.value[2])
|
||||
|
||||
|
|
|
@ -199,9 +199,6 @@ class Importer:
|
|||
serializer_kwargs = {}
|
||||
model_instance = existing_models.first()
|
||||
if not isinstance(model(), BaseMetaModel) and model_instance:
|
||||
if entry.get_state(self.__import) == BlueprintEntryDesiredState.CREATED:
|
||||
self.logger.debug("instance exists, skipping")
|
||||
return None
|
||||
self.logger.debug(
|
||||
"initialise serializer with instance",
|
||||
model=model,
|
||||
|
@ -268,21 +265,34 @@ class Importer:
|
|||
try:
|
||||
serializer = self._validate_single(entry)
|
||||
except EntryInvalidError as exc:
|
||||
# For deleting objects we don't need the serializer to be valid
|
||||
if entry.get_state(self.__import) == BlueprintEntryDesiredState.ABSENT:
|
||||
continue
|
||||
self.logger.warning(f"entry invalid: {exc}", entry=entry, error=exc)
|
||||
return False
|
||||
if not serializer:
|
||||
continue
|
||||
|
||||
state = entry.get_state(self.__import)
|
||||
if state in [
|
||||
BlueprintEntryDesiredState.PRESENT,
|
||||
BlueprintEntryDesiredState.CREATED,
|
||||
]:
|
||||
model = serializer.save()
|
||||
if state in [BlueprintEntryDesiredState.PRESENT, BlueprintEntryDesiredState.CREATED]:
|
||||
instance = serializer.instance
|
||||
if (
|
||||
instance
|
||||
and not instance._state.adding
|
||||
and state == BlueprintEntryDesiredState.CREATED
|
||||
):
|
||||
self.logger.debug(
|
||||
"instance exists, skipping",
|
||||
model=model,
|
||||
instance=instance,
|
||||
pk=instance.pk,
|
||||
)
|
||||
else:
|
||||
instance = serializer.save()
|
||||
self.logger.debug("updated model", model=instance)
|
||||
if "pk" in entry.identifiers:
|
||||
self.__pk_map[entry.identifiers["pk"]] = model.pk
|
||||
entry._state = BlueprintEntryState(model)
|
||||
self.logger.debug("updated model", model=model)
|
||||
self.__pk_map[entry.identifiers["pk"]] = instance.pk
|
||||
entry._state = BlueprintEntryState(instance)
|
||||
elif state == BlueprintEntryDesiredState.ABSENT:
|
||||
instance: Optional[Model] = serializer.instance
|
||||
if instance.pk:
|
||||
|
@ -309,5 +319,6 @@ class Importer:
|
|||
self.logger.debug("Blueprint validation failed")
|
||||
for log in logs:
|
||||
getattr(self.logger, log.get("log_level"))(**log)
|
||||
self.logger.debug("Finished blueprint import validation")
|
||||
self.__import = orig_import
|
||||
return successful, logs
|
||||
|
|
|
@ -1,55 +1,11 @@
|
|||
# Generated by Django 3.2.8 on 2021-10-10 16:16
|
||||
|
||||
from os import environ
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.apps.registry import Apps
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
|
||||
import authentik.core.models
|
||||
|
||||
|
||||
def create_default_user(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
from django.contrib.auth.hashers import make_password
|
||||
|
||||
User = apps.get_model("authentik_core", "User")
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
akadmin, _ = User.objects.using(db_alias).get_or_create(
|
||||
username="akadmin",
|
||||
email=environ.get("AUTHENTIK_BOOTSTRAP_EMAIL", "root@localhost"),
|
||||
name="authentik Default Admin",
|
||||
)
|
||||
password = None
|
||||
if "TF_BUILD" in environ or settings.TEST:
|
||||
password = "akadmin" # noqa # nosec
|
||||
if "AUTHENTIK_BOOTSTRAP_PASSWORD" in environ:
|
||||
password = environ["AUTHENTIK_BOOTSTRAP_PASSWORD"]
|
||||
if password:
|
||||
akadmin.password = make_password(password)
|
||||
else:
|
||||
akadmin.password = make_password(None)
|
||||
akadmin.save()
|
||||
|
||||
|
||||
def create_default_admin_group(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
db_alias = schema_editor.connection.alias
|
||||
Group = apps.get_model("authentik_core", "Group")
|
||||
User = apps.get_model("authentik_core", "User")
|
||||
|
||||
# Creates a default admin group
|
||||
group, _ = Group.objects.using(db_alias).get_or_create(
|
||||
is_superuser=True,
|
||||
defaults={
|
||||
"name": "authentik Admins",
|
||||
},
|
||||
)
|
||||
group.users.set(User.objects.filter(username="akadmin"))
|
||||
group.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
replaces = [
|
||||
("authentik_core", "0002_auto_20200523_1133"),
|
||||
|
@ -119,9 +75,6 @@ class Migration(migrations.Migration):
|
|||
model_name="user",
|
||||
name="is_staff",
|
||||
),
|
||||
migrations.RunPython(
|
||||
code=create_default_user,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="is_superuser",
|
||||
|
@ -201,9 +154,6 @@ class Migration(migrations.Migration):
|
|||
default=False, help_text="Users added to this group will be superusers."
|
||||
),
|
||||
),
|
||||
migrations.RunPython(
|
||||
code=create_default_admin_group,
|
||||
),
|
||||
migrations.AlterModelManagers(
|
||||
name="user",
|
||||
managers=[
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Generated by Django 3.2.8 on 2021-10-10 16:12
|
||||
|
||||
import uuid
|
||||
from os import environ
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.apps.registry import Apps
|
||||
|
@ -35,29 +34,6 @@ def fix_duplicates(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
|||
Token.objects.using(db_alias).filter(identifier=ident["identifier"]).delete()
|
||||
|
||||
|
||||
def create_default_user_token(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
from authentik.core.models import TokenIntents
|
||||
|
||||
User = apps.get_model("authentik_core", "User")
|
||||
Token = apps.get_model("authentik_core", "Token")
|
||||
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
akadmin = User.objects.using(db_alias).filter(username="akadmin")
|
||||
if not akadmin.exists():
|
||||
return
|
||||
if "AUTHENTIK_BOOTSTRAP_TOKEN" not in environ:
|
||||
return
|
||||
key = environ["AUTHENTIK_BOOTSTRAP_TOKEN"]
|
||||
Token.objects.using(db_alias).create(
|
||||
identifier="authentik-bootstrap-token",
|
||||
user=akadmin.first(),
|
||||
intent=TokenIntents.INTENT_API,
|
||||
expiring=False,
|
||||
key=key,
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
replaces = [
|
||||
("authentik_core", "0018_auto_20210330_1345"),
|
||||
|
@ -214,9 +190,6 @@ class Migration(migrations.Migration):
|
|||
"verbose_name_plural": "Authenticated Sessions",
|
||||
},
|
||||
),
|
||||
migrations.RunPython(
|
||||
code=create_default_user_token,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="token",
|
||||
name="intent",
|
||||
|
|
|
@ -60,7 +60,7 @@ def default_token_key():
|
|||
"""Default token key"""
|
||||
# We use generate_id since the chars in the key should be easy
|
||||
# to use in Emails (for verification) and URLs (for recovery)
|
||||
return generate_id(int(CONFIG.get("default_token_length")))
|
||||
return generate_id(CONFIG.get_int("default_token_length"))
|
||||
|
||||
|
||||
class UserTypes(models.TextChoices):
|
||||
|
|
|
@ -33,7 +33,7 @@ PLAN_CONTEXT_SOURCE = "source"
|
|||
# Is set by the Flow Planner when a FlowToken was used, and the currently active flow plan
|
||||
# was restored.
|
||||
PLAN_CONTEXT_IS_RESTORED = "is_restored"
|
||||
CACHE_TIMEOUT = int(CONFIG.get("redis.cache_timeout_flows"))
|
||||
CACHE_TIMEOUT = CONFIG.get_int("redis.cache_timeout_flows")
|
||||
CACHE_PREFIX = "goauthentik.io/flows/planner/"
|
||||
|
||||
|
||||
|
|
|
@ -213,6 +213,14 @@ class ConfigLoader:
|
|||
attr: Attr = get_path_from_dict(root, path, sep=sep, default=Attr(default))
|
||||
return attr.value
|
||||
|
||||
def get_int(self, path: str, default=0) -> int:
|
||||
"""Wrapper for get that converts value into int"""
|
||||
try:
|
||||
return int(self.get(path, default))
|
||||
except ValueError as exc:
|
||||
self.log("warning", "Failed to parse config as int", path=path, exc=str(exc))
|
||||
return default
|
||||
|
||||
def get_bool(self, path: str, default=False) -> bool:
|
||||
"""Wrapper for get that converts value into boolean"""
|
||||
return str(self.get(path, default)).lower() == "true"
|
||||
|
|
|
@ -98,7 +98,7 @@ def traces_sampler(sampling_context: dict) -> float:
|
|||
def before_send(event: dict, hint: dict) -> Optional[dict]:
|
||||
"""Check if error is database error, and ignore if so"""
|
||||
# pylint: disable=no-name-in-module
|
||||
from psycopg2.errors import Error
|
||||
from psycopg.errors import Error
|
||||
|
||||
ignored_classes = (
|
||||
# Inbuilt types
|
||||
|
|
|
@ -79,3 +79,15 @@ class TestConfig(TestCase):
|
|||
config.update_from_file(file2_name)
|
||||
unlink(file_name)
|
||||
unlink(file2_name)
|
||||
|
||||
def test_get_int(self):
|
||||
"""Test get_int"""
|
||||
config = ConfigLoader()
|
||||
config.set("foo", 1234)
|
||||
self.assertEqual(config.get_int("foo"), 1234)
|
||||
|
||||
def test_get_int_invalid(self):
|
||||
"""Test get_int"""
|
||||
config = ConfigLoader()
|
||||
config.set("foo", "bar")
|
||||
self.assertEqual(config.get_int("foo", 1234), 1234)
|
||||
|
|
|
@ -19,7 +19,7 @@ from authentik.policies.types import CACHE_PREFIX, PolicyRequest, PolicyResult
|
|||
LOGGER = get_logger()
|
||||
|
||||
FORK_CTX = get_context("fork")
|
||||
CACHE_TIMEOUT = int(CONFIG.get("redis.cache_timeout_policies"))
|
||||
CACHE_TIMEOUT = CONFIG.get_int("redis.cache_timeout_policies")
|
||||
PROCESS_CLASS = FORK_CTX.Process
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ from authentik.policies.reputation.tasks import save_reputation
|
|||
from authentik.stages.identification.signals import identification_failed
|
||||
|
||||
LOGGER = get_logger()
|
||||
CACHE_TIMEOUT = int(CONFIG.get("redis.cache_timeout_reputation"))
|
||||
CACHE_TIMEOUT = CONFIG.get_int("redis.cache_timeout_reputation")
|
||||
|
||||
|
||||
def update_score(request: HttpRequest, identifier: str, amount: int):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""id_token utils"""
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union
|
||||
|
||||
from django.db import models
|
||||
from django.http import HttpRequest
|
||||
|
@ -57,7 +57,7 @@ class IDToken:
|
|||
# Subject, https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.2
|
||||
sub: Optional[str] = None
|
||||
# Audience, https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3
|
||||
aud: Optional[str] = None
|
||||
aud: Optional[Union[str, list[str]]] = None
|
||||
# Expiration time, https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4
|
||||
exp: Optional[int] = None
|
||||
# Issued at, https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.6
|
||||
|
|
|
@ -44,7 +44,11 @@ def config_loggers(*args, **kwargs):
|
|||
def after_task_publish_hook(sender=None, headers=None, body=None, **kwargs):
|
||||
"""Log task_id after it was published"""
|
||||
info = headers if "task" in headers else body
|
||||
LOGGER.info("Task published", task_id=info.get("id", ""), task_name=info.get("task", ""))
|
||||
LOGGER.info(
|
||||
"Task published",
|
||||
task_id=info.get("id", "").replace("-", ""),
|
||||
task_name=info.get("task", ""),
|
||||
)
|
||||
|
||||
|
||||
@task_prerun.connect
|
||||
|
@ -59,7 +63,9 @@ def task_prerun_hook(task_id: str, task, *args, **kwargs):
|
|||
def task_postrun_hook(task_id, task, *args, retval=None, state=None, **kwargs):
|
||||
"""Log task_id on worker"""
|
||||
CTX_TASK_ID.set(...)
|
||||
LOGGER.info("Task finished", task_id=task_id, task_name=task.__name__, state=state)
|
||||
LOGGER.info(
|
||||
"Task finished", task_id=task_id.replace("-", ""), task_name=task.__name__, state=state
|
||||
)
|
||||
|
||||
|
||||
@task_failure.connect
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from functools import lru_cache
|
||||
from uuid import uuid4
|
||||
|
||||
from psycopg2 import connect
|
||||
from psycopg import connect
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
|
||||
|
@ -30,7 +30,7 @@ def get_install_id_raw():
|
|||
user=CONFIG.get("postgresql.user"),
|
||||
password=CONFIG.get("postgresql.password"),
|
||||
host=CONFIG.get("postgresql.host"),
|
||||
port=int(CONFIG.get("postgresql.port")),
|
||||
port=CONFIG.get_int("postgresql.port"),
|
||||
sslmode=CONFIG.get("postgresql.sslmode"),
|
||||
sslrootcert=CONFIG.get("postgresql.sslrootcert"),
|
||||
sslcert=CONFIG.get("postgresql.sslcert"),
|
||||
|
|
|
@ -190,14 +190,14 @@ if CONFIG.get_bool("redis.tls", False):
|
|||
_redis_url = (
|
||||
f"{_redis_protocol_prefix}:"
|
||||
f"{quote_plus(CONFIG.get('redis.password'))}@{quote_plus(CONFIG.get('redis.host'))}:"
|
||||
f"{int(CONFIG.get('redis.port'))}"
|
||||
f"{CONFIG.get_int('redis.port')}"
|
||||
)
|
||||
|
||||
CACHES = {
|
||||
"default": {
|
||||
"BACKEND": "django_redis.cache.RedisCache",
|
||||
"LOCATION": f"{_redis_url}/{CONFIG.get('redis.db')}",
|
||||
"TIMEOUT": int(CONFIG.get("redis.cache_timeout", 300)),
|
||||
"TIMEOUT": CONFIG.get_int("redis.cache_timeout", 300),
|
||||
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
|
||||
"KEY_PREFIX": "authentik_cache",
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ DATABASES = {
|
|||
"NAME": CONFIG.get("postgresql.name"),
|
||||
"USER": CONFIG.get("postgresql.user"),
|
||||
"PASSWORD": CONFIG.get("postgresql.password"),
|
||||
"PORT": int(CONFIG.get("postgresql.port")),
|
||||
"PORT": CONFIG.get_int("postgresql.port"),
|
||||
"SSLMODE": CONFIG.get("postgresql.sslmode"),
|
||||
"SSLROOTCERT": CONFIG.get("postgresql.sslrootcert"),
|
||||
"SSLCERT": CONFIG.get("postgresql.sslcert"),
|
||||
|
@ -293,12 +293,12 @@ if CONFIG.get_bool("postgresql.use_pgbouncer", False):
|
|||
# loads the config directly from CONFIG
|
||||
# See authentik/stages/email/models.py, line 105
|
||||
EMAIL_HOST = CONFIG.get("email.host")
|
||||
EMAIL_PORT = int(CONFIG.get("email.port"))
|
||||
EMAIL_PORT = CONFIG.get_int("email.port")
|
||||
EMAIL_HOST_USER = CONFIG.get("email.username")
|
||||
EMAIL_HOST_PASSWORD = CONFIG.get("email.password")
|
||||
EMAIL_USE_TLS = CONFIG.get_bool("email.use_tls", False)
|
||||
EMAIL_USE_SSL = CONFIG.get_bool("email.use_ssl", False)
|
||||
EMAIL_TIMEOUT = int(CONFIG.get("email.timeout"))
|
||||
EMAIL_TIMEOUT = CONFIG.get_int("email.timeout")
|
||||
DEFAULT_FROM_EMAIL = CONFIG.get("email.from")
|
||||
SERVER_EMAIL = DEFAULT_FROM_EMAIL
|
||||
EMAIL_SUBJECT_PREFIX = "[authentik] "
|
||||
|
|
|
@ -93,7 +93,7 @@ class BaseLDAPSynchronizer:
|
|||
types_only=False,
|
||||
get_operational_attributes=False,
|
||||
controls=None,
|
||||
paged_size=int(CONFIG.get("ldap.page_size", 50)),
|
||||
paged_size=CONFIG.get_int("ldap.page_size", 50),
|
||||
paged_criticality=False,
|
||||
):
|
||||
"""Search in pages, returns each page"""
|
||||
|
|
|
@ -59,7 +59,7 @@ def ldap_sync_paginator(source: LDAPSource, sync: type[BaseLDAPSynchronizer]) ->
|
|||
signatures = []
|
||||
for page in sync_inst.get_objects():
|
||||
page_cache_key = CACHE_KEY_PREFIX + str(uuid4())
|
||||
cache.set(page_cache_key, page, 60 * 60 * int(CONFIG.get("ldap.task_timeout_hours")))
|
||||
cache.set(page_cache_key, page, 60 * 60 * CONFIG.get_int("ldap.task_timeout_hours"))
|
||||
page_sync = ldap_sync.si(source.pk, class_to_path(sync), page_cache_key)
|
||||
signatures.append(page_sync)
|
||||
return signatures
|
||||
|
@ -68,12 +68,12 @@ def ldap_sync_paginator(source: LDAPSource, sync: type[BaseLDAPSynchronizer]) ->
|
|||
@CELERY_APP.task(
|
||||
bind=True,
|
||||
base=MonitoredTask,
|
||||
soft_time_limit=60 * 60 * int(CONFIG.get("ldap.task_timeout_hours")),
|
||||
task_time_limit=60 * 60 * int(CONFIG.get("ldap.task_timeout_hours")),
|
||||
soft_time_limit=60 * 60 * CONFIG.get_int("ldap.task_timeout_hours"),
|
||||
task_time_limit=60 * 60 * CONFIG.get_int("ldap.task_timeout_hours"),
|
||||
)
|
||||
def ldap_sync(self: MonitoredTask, source_pk: str, sync_class: str, page_cache_key: str):
|
||||
"""Synchronization of an LDAP Source"""
|
||||
self.result_timeout_hours = int(CONFIG.get("ldap.task_timeout_hours"))
|
||||
self.result_timeout_hours = CONFIG.get_int("ldap.task_timeout_hours")
|
||||
source: LDAPSource = LDAPSource.objects.filter(pk=source_pk).first()
|
||||
if not source:
|
||||
# Because the source couldn't be found, we don't have a UID
|
||||
|
|
|
@ -108,12 +108,12 @@ class EmailStage(Stage):
|
|||
CONFIG.refresh("email.password")
|
||||
return self.backend_class(
|
||||
host=CONFIG.get("email.host"),
|
||||
port=int(CONFIG.get("email.port")),
|
||||
port=CONFIG.get_int("email.port"),
|
||||
username=CONFIG.get("email.username"),
|
||||
password=CONFIG.get("email.password"),
|
||||
use_tls=CONFIG.get_bool("email.use_tls", False),
|
||||
use_ssl=CONFIG.get_bool("email.use_ssl", False),
|
||||
timeout=int(CONFIG.get("email.timeout")),
|
||||
timeout=CONFIG.get_int("email.timeout"),
|
||||
)
|
||||
return self.backend_class(
|
||||
host=self.host,
|
||||
|
|
|
@ -2,6 +2,12 @@ version: 1
|
|||
metadata:
|
||||
name: Default - Events Transport & Rules
|
||||
entries:
|
||||
# Run bootstrap blueprint first to ensure we have the group created
|
||||
- model: authentik_blueprints.metaapplyblueprint
|
||||
attrs:
|
||||
identifiers:
|
||||
path: system/bootstrap.yaml
|
||||
required: false
|
||||
- model: authentik_events.notificationtransport
|
||||
id: default-email-transport
|
||||
attrs:
|
||||
|
@ -16,6 +22,7 @@ entries:
|
|||
name: default-local-transport
|
||||
- model: authentik_core.group
|
||||
id: group
|
||||
state: created
|
||||
identifiers:
|
||||
name: authentik Admins
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
version: 1
|
||||
metadata:
|
||||
name: Migration - Remove old prompt fields
|
||||
labels:
|
||||
blueprints.goauthentik.io/description: Migrate to 2023.2, remove unused prompt fields
|
||||
name: Migration - Remove old prompt fields
|
||||
entries:
|
||||
- model: authentik_stages_prompt.prompt
|
||||
identifiers:
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
version: 1
|
||||
metadata:
|
||||
name: authentik Bootstrap
|
||||
labels:
|
||||
blueprints.goauthentik.io/system-bootstrap: "true"
|
||||
blueprints.goauthentik.io/system: "true"
|
||||
blueprints.goauthentik.io/description: |
|
||||
This blueprint configures the default admin user and group, and configures them for the [Automated install](https://goauthentik.io/docs/installation/automated-install).
|
||||
context:
|
||||
username: akadmin
|
||||
group_name: authentik Admins
|
||||
email: !Env [AUTHENTIK_BOOTSTRAP_EMAIL, "root@example.com"]
|
||||
password: !Env [AUTHENTIK_BOOTSTRAP_PASSWORD, null]
|
||||
token: !Env [AUTHENTIK_BOOTSTRAP_TOKEN, null]
|
||||
entries:
|
||||
- model: authentik_core.group
|
||||
state: created
|
||||
identifiers:
|
||||
name: !Context group_name
|
||||
attrs:
|
||||
is_superuser: true
|
||||
id: admin-group
|
||||
- model: authentik_core.user
|
||||
state: created
|
||||
id: admin-user
|
||||
identifiers:
|
||||
username: !Context username
|
||||
attrs:
|
||||
name: authentik Default Admin
|
||||
email: !Context email
|
||||
groups:
|
||||
- !KeyOf admin-group
|
||||
password: !Context password
|
||||
- model: authentik_core.token
|
||||
state: created
|
||||
conditions:
|
||||
- !If [!Context token]
|
||||
identifiers:
|
||||
identifier: authentik-bootstrap-token
|
||||
intent: api
|
||||
expiring: false
|
||||
key: !Context token
|
||||
user: !KeyOf admin-user
|
||||
- model: authentik_blueprints.blueprintinstance
|
||||
identifiers:
|
||||
metadata:
|
||||
labels:
|
||||
blueprints.goauthentik.io/system-bootstrap: "true"
|
||||
state: absent
|
6
go.mod
|
@ -7,7 +7,7 @@ require (
|
|||
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/garyburd/redigo v1.6.4
|
||||
github.com/getsentry/sentry-go v0.22.0
|
||||
github.com/getsentry/sentry-go v0.23.0
|
||||
github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1
|
||||
github.com/go-ldap/ldap/v3 v3.4.5
|
||||
github.com/go-openapi/runtime v0.26.0
|
||||
|
@ -26,7 +26,7 @@ require (
|
|||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
goauthentik.io/api/v3 v3.2023061.6
|
||||
goauthentik.io/api/v3 v3.2023061.7
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.10.0
|
||||
golang.org/x/sync v0.3.0
|
||||
|
@ -74,7 +74,7 @@ require (
|
|||
go.opentelemetry.io/otel v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.14.0 // indirect
|
||||
golang.org/x/crypto v0.11.0 // indirect
|
||||
golang.org/x/net v0.12.0 // indirect
|
||||
golang.org/x/net v0.13.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
|
11
go.sum
|
@ -681,8 +681,8 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/
|
|||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/garyburd/redigo v1.6.4 h1:LFu2R3+ZOPgSMWMOL+saa/zXRjw0ID2G8FepO53BGlg=
|
||||
github.com/garyburd/redigo v1.6.4/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw=
|
||||
github.com/getsentry/sentry-go v0.22.0 h1:XNX9zKbv7baSEI65l+H1GEJgSeIC1c7EN5kluWaP6dM=
|
||||
github.com/getsentry/sentry-go v0.22.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
|
||||
github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE=
|
||||
github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
|
@ -1070,8 +1070,8 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
|
|||
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||
goauthentik.io/api/v3 v3.2023061.6 h1:4zbo0Dtx42HLYObizIlTWAk7iBvCv9kmCvzBxMElkIk=
|
||||
goauthentik.io/api/v3 v3.2023061.6/go.mod h1:tC7qK9VSP0zJah5p5xHFnjZt/4dAkXVwcrWyZNGYhwQ=
|
||||
goauthentik.io/api/v3 v3.2023061.7 h1:uxN57usnWEyBjlbp+0npSv1HNlwrCUhVMu8Gtoabgqk=
|
||||
goauthentik.io/api/v3 v3.2023061.7/go.mod h1:JWRqmfaXtI9vMljPXbzzIF70rjn55v0iEZkFVNDXvwk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
|
@ -1213,8 +1213,9 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
|
||||
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Stage 1: Build
|
||||
FROM docker.io/golang:1.20.6-bullseye AS builder
|
||||
FROM docker.io/golang:1.20.7-bullseye AS builder
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
|
|
|
@ -80,8 +80,8 @@ if SERVICE_HOST_ENV_NAME in os.environ:
|
|||
else:
|
||||
default_workers = max(cpu_count() * 0.25, 1) + 1 # Minimum of 2 workers
|
||||
|
||||
workers = int(CONFIG.get("web.workers", default_workers))
|
||||
threads = int(CONFIG.get("web.threads", 4))
|
||||
workers = CONFIG.get_int("web.workers", default_workers)
|
||||
threads = CONFIG.get_int("web.threads", 4)
|
||||
|
||||
|
||||
def post_fork(server: "Arbiter", worker: DjangoUvicornWorker):
|
||||
|
|
|
@ -6,7 +6,7 @@ from inspect import getmembers, isclass
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from psycopg2 import connect
|
||||
from psycopg import connect
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
|
@ -56,7 +56,7 @@ if __name__ == "__main__":
|
|||
user=CONFIG.get("postgresql.user"),
|
||||
password=CONFIG.get("postgresql.password"),
|
||||
host=CONFIG.get("postgresql.host"),
|
||||
port=int(CONFIG.get("postgresql.port")),
|
||||
port=CONFIG.get_int("postgresql.port"),
|
||||
sslmode=CONFIG.get("postgresql.sslmode"),
|
||||
sslrootcert=CONFIG.get("postgresql.sslrootcert"),
|
||||
sslcert=CONFIG.get("postgresql.sslcert"),
|
||||
|
|
|
@ -5,7 +5,7 @@ from sys import exit as sysexit
|
|||
from time import sleep
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
from psycopg2 import OperationalError, connect
|
||||
from psycopg import OperationalError, connect
|
||||
from redis import Redis
|
||||
from redis.exceptions import RedisError
|
||||
|
||||
|
@ -28,7 +28,7 @@ while True:
|
|||
user=CONFIG.get("postgresql.user"),
|
||||
password=CONFIG.get("postgresql.password"),
|
||||
host=CONFIG.get("postgresql.host"),
|
||||
port=int(CONFIG.get("postgresql.port")),
|
||||
port=CONFIG.get_int("postgresql.port"),
|
||||
sslmode=CONFIG.get("postgresql.sslmode"),
|
||||
sslrootcert=CONFIG.get("postgresql.sslrootcert"),
|
||||
sslcert=CONFIG.get("postgresql.sslcert"),
|
||||
|
@ -47,7 +47,7 @@ if CONFIG.get_bool("redis.tls", False):
|
|||
REDIS_URL = (
|
||||
f"{REDIS_PROTOCOL_PREFIX}:"
|
||||
f"{quote_plus(CONFIG.get('redis.password'))}@{quote_plus(CONFIG.get('redis.host'))}:"
|
||||
f"{int(CONFIG.get('redis.port'))}/{CONFIG.get('redis.db')}"
|
||||
f"{CONFIG.get_int('redis.port')}/{CONFIG.get('redis.db')}"
|
||||
)
|
||||
while True:
|
||||
try:
|
||||
|
|
|
@ -8,7 +8,7 @@ WORKDIR /static
|
|||
RUN npm ci --include=dev && npm run build-proxy
|
||||
|
||||
# Stage 2: Build
|
||||
FROM docker.io/golang:1.20.6-bullseye AS builder
|
||||
FROM docker.io/golang:1.20.7-bullseye AS builder
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ colorama = "*"
|
|||
dacite = "*"
|
||||
deepmerge = "*"
|
||||
defusedxml = "*"
|
||||
django = "<4.2.0"
|
||||
django = "*"
|
||||
django-filter = "*"
|
||||
django-guardian = "*"
|
||||
django-model-utils = "*"
|
||||
|
@ -150,7 +150,7 @@ lxml = "*"
|
|||
opencontainers = { extras = ["reggie"], version = "*" }
|
||||
packaging = "*"
|
||||
paramiko = "*"
|
||||
psycopg2-binary = "*"
|
||||
psycopg = { extras = ["c"], version = "*" }
|
||||
pycryptodome = "*"
|
||||
pydantic = "<2.0.0"
|
||||
pydantic-scim = "^0.0.7"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Stage 1: Build
|
||||
FROM docker.io/golang:1.20.6-bullseye AS builder
|
||||
FROM docker.io/golang:1.20.7-bullseye AS builder
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import replace from "@rollup/plugin-replace";
|
||||
import type { StorybookConfig } from "@storybook/web-components-vite";
|
||||
import path from "path";
|
||||
import { cwd } from "process";
|
||||
import postcssLit from "rollup-plugin-postcss-lit";
|
||||
import tsconfigPaths from "vite-tsconfig-paths";
|
||||
|
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 12 KiB |
|
@ -16,24 +16,25 @@
|
|||
"@codemirror/legacy-modes": "^6.3.3",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.4.0",
|
||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||
"@fortawesome/fontawesome-free": "^6.4.2",
|
||||
"@goauthentik/api": "^2023.6.1-1690455444",
|
||||
"@lit-labs/context": "^0.3.3",
|
||||
"@lit-labs/task": "^2.1.2",
|
||||
"@lit-labs/task": "^3.0.0",
|
||||
"@lit/localize": "^0.11.4",
|
||||
"@patternfly/elements": "^2.3.2",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.60.1",
|
||||
"@sentry/tracing": "^7.60.1",
|
||||
"@sentry/browser": "^7.61.0",
|
||||
"@sentry/tracing": "^7.61.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.3.2",
|
||||
"chart.js": "^4.3.3",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.32.0",
|
||||
"country-flag-icons": "^1.5.7",
|
||||
"fuse.js": "^6.6.2",
|
||||
"lit": "^2.7.6",
|
||||
"lit": "^2.8.0",
|
||||
"mermaid": "^10.3.0",
|
||||
"rapidoc": "^9.3.4",
|
||||
"style-mod": "^4.0.3",
|
||||
|
@ -67,8 +68,8 @@
|
|||
"@types/chart.js": "^2.9.37",
|
||||
"@types/codemirror": "5.60.8",
|
||||
"@types/grecaptcha": "^3.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
||||
"@typescript-eslint/parser": "^6.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
||||
"@typescript-eslint/parser": "^6.2.1",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"eslint": "^8.46.0",
|
||||
|
@ -78,8 +79,8 @@
|
|||
"eslint-plugin-storybook": "^0.6.13",
|
||||
"lit-analyzer": "^1.2.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.0.0",
|
||||
"pyright": "^1.1.319",
|
||||
"prettier": "^3.0.1",
|
||||
"pyright": "^1.1.320",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"rollup": "^2.79.1",
|
||||
|
@ -2853,6 +2854,28 @@
|
|||
"integrity": "sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz",
|
||||
"integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz",
|
||||
"integrity": "sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.4.1",
|
||||
"@floating-ui/utils": "^0.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz",
|
||||
"integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw=="
|
||||
},
|
||||
"node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz",
|
||||
|
@ -2881,9 +2904,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-free": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.0.tgz",
|
||||
"integrity": "sha512-0NyytTlPJwB/BF5LtRV8rrABDbe3TdTXqNB3PdZ+UUUZAEIrdOJdmABqKjt4AXwIoJNaRVVZEXxpNrqvE1GAYQ==",
|
||||
"version": "6.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz",
|
||||
"integrity": "sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg==",
|
||||
"hasInstallScript": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
|
@ -3463,9 +3486,9 @@
|
|||
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
|
||||
},
|
||||
"node_modules/@lit-labs/task": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@lit-labs/task/-/task-2.1.2.tgz",
|
||||
"integrity": "sha512-pDjPYojmCXnOezT/4BgqxHA2kahmSsCE0y6uPCYyVqigIx9DJav05s0KAtD9IImTY3LvWu5isSlq6nkWagAybA==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@lit-labs/task/-/task-3.0.0.tgz",
|
||||
"integrity": "sha512-h5Jh7PnJrQ10QABddGGmnCEdZyCveCCz/FDg4wLX7/tZQc281zJaxaTFnozUUqpessPjSzOOvQjF19p2QdThXg==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^1.1.0"
|
||||
}
|
||||
|
@ -3612,11 +3635,46 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@patternfly/elements": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@patternfly/elements/-/elements-2.3.2.tgz",
|
||||
"integrity": "sha512-cndt+xxlUKbWU8GxFlOXMNqNeJ792kXUnvcYZbUIA+TUbWD71yw0kdC+EOWql94B4jtzOmDyG7Eq33il3G6ZLQ==",
|
||||
"dependencies": {
|
||||
"@patternfly/icons": "^1.0.2",
|
||||
"@patternfly/pfe-core": "^2.4.0",
|
||||
"lit": "2.6.1",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@patternfly/elements/node_modules/lit": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz",
|
||||
"integrity": "sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^1.6.0",
|
||||
"lit-element": "^3.2.0",
|
||||
"lit-html": "^2.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@patternfly/icons": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@patternfly/icons/-/icons-1.0.2.tgz",
|
||||
"integrity": "sha512-/faOTZsKkTPxuCDcWZbunknjUhJIjjN0h+OicNiFWxTq/saLp366cLhdgNf8A46oeGR/21aQTYVXTqcQA1yvOg=="
|
||||
},
|
||||
"node_modules/@patternfly/patternfly": {
|
||||
"version": "4.224.2",
|
||||
"resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.224.2.tgz",
|
||||
"integrity": "sha512-HGNV26uyHSIECuhjPg/WGn0mXbAotcs6ODfhAOkfYjIgGylddgiwElxUe1rpEHV5mQJJ2rMn4OdeJIIpzRX61g=="
|
||||
},
|
||||
"node_modules/@patternfly/pfe-core": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@patternfly/pfe-core/-/pfe-core-2.4.1.tgz",
|
||||
"integrity": "sha512-ZqN4Zk2ysrnHp84hKvUr54xeSwtzqM3qRPpMzdd2fa58htYnPfhow4TQ8LH9vArLxPzEAB3Hrfql0VW1bk5PXw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.2.6",
|
||||
"lit": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
|
@ -3773,13 +3831,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/tracing": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.60.1.tgz",
|
||||
"integrity": "sha512-2vM+3/ddzmoBfi92OOD9FFTHXf0HdQhKtNM26+/RsmkKnTid+/inbvA7nKi+Qa7ExcnlC6eclEHQEg+0X3yDkQ==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.61.0.tgz",
|
||||
"integrity": "sha512-zTr+MXEG4SxNxif42LIgm2RQn+JRXL2NuGhRaKSD2i4lXKFqHVGlVdoWqY5UfqnnJPokiTWIj9ejR8I5HV8Ogw==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.60.1",
|
||||
"@sentry/types": "7.60.1",
|
||||
"@sentry/utils": "7.60.1",
|
||||
"@sentry/core": "7.61.0",
|
||||
"@sentry/types": "7.61.0",
|
||||
"@sentry/utils": "7.61.0",
|
||||
"tslib": "^2.4.1 || ^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -3787,15 +3845,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@sentry/browser": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.60.1.tgz",
|
||||
"integrity": "sha512-opZQee3S0c459LXt8YGpwOM/qiTlzluHEEnfW2q+D2yVCWh8iegsDX3kbRiv4i/mtQu9yPhM9M761KDnc/0eZw==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.61.0.tgz",
|
||||
"integrity": "sha512-IGEkJZRP16Oe5CkXkmhU3QdV5RugW6Vds16yJFFYsgp87NprWtRZgqzldFDYkINStfBHVdctj/Rh/ZrLf8QlkQ==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.60.1",
|
||||
"@sentry/core": "7.60.1",
|
||||
"@sentry/replay": "7.60.1",
|
||||
"@sentry/types": "7.60.1",
|
||||
"@sentry/utils": "7.60.1",
|
||||
"@sentry-internal/tracing": "7.61.0",
|
||||
"@sentry/core": "7.61.0",
|
||||
"@sentry/replay": "7.61.0",
|
||||
"@sentry/types": "7.61.0",
|
||||
"@sentry/utils": "7.61.0",
|
||||
"tslib": "^2.4.1 || ^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -3803,12 +3861,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.60.1.tgz",
|
||||
"integrity": "sha512-yr/0VFYWOJyXj+F2nifkRYxXskotsNnDggUnFOZZN2ZgTG94IzRFsOZQ6RslHJ8nrYPTBNO74reU0C0GB++xRw==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.61.0.tgz",
|
||||
"integrity": "sha512-zl0ZKRjIoYJQWYTd3K/U6zZfS4GDY9yGd2EH4vuYO4kfYtEp/nJ8A+tfAeDo0c9FGxZ0Q+5t5F4/SfwbgyyQzg==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.60.1",
|
||||
"@sentry/utils": "7.60.1",
|
||||
"@sentry/types": "7.61.0",
|
||||
"@sentry/utils": "7.61.0",
|
||||
"tslib": "^2.4.1 || ^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -3816,43 +3874,43 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@sentry/replay": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.60.1.tgz",
|
||||
"integrity": "sha512-WHQxEpJbHICs12L17LGgS/ql91yn9wJDH/hgb+1H90HaasjoR54ofWCKul29OvYV0snTWuHd6xauwtzyv9tzvg==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.61.0.tgz",
|
||||
"integrity": "sha512-1ugk0yZssOPkSg6uTVcysjxlBydycXiOgV0PCU7DsXCFOV1ua5YpyPZFReTz9iFTtwD0LwGFM1LW9wJeQ67Fzg==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.60.1",
|
||||
"@sentry/types": "7.60.1",
|
||||
"@sentry/utils": "7.60.1"
|
||||
"@sentry/core": "7.61.0",
|
||||
"@sentry/types": "7.61.0",
|
||||
"@sentry/utils": "7.61.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/tracing": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.60.1.tgz",
|
||||
"integrity": "sha512-yzjbFaaOPeMERD5GPaBdKQRihznluYO7O24y0hznROPGOVNozwPX8JZgX0plOfSmCttjYjDwRrIo9nFFpzFhtw==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.61.0.tgz",
|
||||
"integrity": "sha512-asGbw3n04qkM5zUCPlGg9i52GEHq9Nmore38SJFN0L4N/YH6EPJLEUfNm2jFvXWCo96kq/dPKnyjOEuPccwhIA==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.60.1"
|
||||
"@sentry-internal/tracing": "7.61.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/types": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.60.1.tgz",
|
||||
"integrity": "sha512-8lKKSCOhZ953cWxwnfZwoR3ZFFlZG4P3PQFTaFt/u4LxLh/0zYbdtgvtUqXRURjMCi5P6ddeE9Uw9FGnTJCsTw==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.61.0.tgz",
|
||||
"integrity": "sha512-/GLlIBNR35NKPE/SfWi9W10dK9hE8qTShzsuPVn5wAJxpT3Lb4+dkwmKCTLUYxdkmvRDEudkfOxgalsfQGTAWA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils": {
|
||||
"version": "7.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.60.1.tgz",
|
||||
"integrity": "sha512-ik+5sKGBx4DWuvf6UUKPSafaDiASxP+Xvjg3C9ppop2I/JWxP1FfZ5g22n5ZmPmNahD6clTSoTWly8qyDUlUOw==",
|
||||
"version": "7.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.61.0.tgz",
|
||||
"integrity": "sha512-jfj14d0XBFiCU0G6dZZ12SizATiF5Mt4stBGzkM5iS9nXFj8rh1oTT7/p+aZoYzP2JTF+sDzkNjWxyKZkcTo0Q==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.60.1",
|
||||
"@sentry/types": "7.61.0",
|
||||
"tslib": "^2.4.1 || ^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -10737,16 +10795,16 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz",
|
||||
"integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz",
|
||||
"integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "6.2.0",
|
||||
"@typescript-eslint/type-utils": "6.2.0",
|
||||
"@typescript-eslint/utils": "6.2.0",
|
||||
"@typescript-eslint/visitor-keys": "6.2.0",
|
||||
"@typescript-eslint/scope-manager": "6.2.1",
|
||||
"@typescript-eslint/type-utils": "6.2.1",
|
||||
"@typescript-eslint/utils": "6.2.1",
|
||||
"@typescript-eslint/visitor-keys": "6.2.1",
|
||||
"debug": "^4.3.4",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
|
@ -10806,15 +10864,15 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz",
|
||||
"integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz",
|
||||
"integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "6.2.0",
|
||||
"@typescript-eslint/types": "6.2.0",
|
||||
"@typescript-eslint/typescript-estree": "6.2.0",
|
||||
"@typescript-eslint/visitor-keys": "6.2.0",
|
||||
"@typescript-eslint/scope-manager": "6.2.1",
|
||||
"@typescript-eslint/types": "6.2.1",
|
||||
"@typescript-eslint/typescript-estree": "6.2.1",
|
||||
"@typescript-eslint/visitor-keys": "6.2.1",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -10834,13 +10892,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz",
|
||||
"integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz",
|
||||
"integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.2.0",
|
||||
"@typescript-eslint/visitor-keys": "6.2.0"
|
||||
"@typescript-eslint/types": "6.2.1",
|
||||
"@typescript-eslint/visitor-keys": "6.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
|
@ -10851,13 +10909,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz",
|
||||
"integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz",
|
||||
"integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "6.2.0",
|
||||
"@typescript-eslint/utils": "6.2.0",
|
||||
"@typescript-eslint/typescript-estree": "6.2.1",
|
||||
"@typescript-eslint/utils": "6.2.1",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
|
@ -10878,9 +10936,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz",
|
||||
"integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz",
|
||||
"integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
|
@ -10891,13 +10949,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz",
|
||||
"integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz",
|
||||
"integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.2.0",
|
||||
"@typescript-eslint/visitor-keys": "6.2.0",
|
||||
"@typescript-eslint/types": "6.2.1",
|
||||
"@typescript-eslint/visitor-keys": "6.2.1",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
|
@ -10951,17 +11009,17 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz",
|
||||
"integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz",
|
||||
"integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@typescript-eslint/scope-manager": "6.2.0",
|
||||
"@typescript-eslint/types": "6.2.0",
|
||||
"@typescript-eslint/typescript-estree": "6.2.0",
|
||||
"@typescript-eslint/scope-manager": "6.2.1",
|
||||
"@typescript-eslint/types": "6.2.1",
|
||||
"@typescript-eslint/typescript-estree": "6.2.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -11009,12 +11067,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz",
|
||||
"integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz",
|
||||
"integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.2.0",
|
||||
"@typescript-eslint/types": "6.2.1",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -12009,9 +12067,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.3.2.tgz",
|
||||
"integrity": "sha512-pvQNyFOY1QmbmIr8oDORL16/FFivfxj8V26VFpFilMo4cNvkV5WXLJetDio365pd9gKUHGdirUTbqJfw8tr+Dg==",
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.3.3.tgz",
|
||||
"integrity": "sha512-aTk7pBw+x6sQYhon/NR3ikfUJuym/LdgpTlgZRe2PaEhjUMKBKyNaFCMVRAyTEWYFNO7qRu7iQVqOw/OqzxZxQ==",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
|
@ -17039,13 +17097,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/lit": {
|
||||
"version": "2.7.6",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.6.tgz",
|
||||
"integrity": "sha512-1amFHA7t4VaaDe+vdQejSVBklwtH9svGoG6/dZi9JhxtJBBlqY5D1RV7iLUYY0trCqQc4NfhYYZilZiVHt7Hxg==",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
|
||||
"integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^1.6.0",
|
||||
"lit-element": "^3.3.0",
|
||||
"lit-html": "^2.7.0"
|
||||
"lit-html": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lit-analyzer": {
|
||||
|
@ -17272,9 +17330,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lit-html": {
|
||||
"version": "2.7.5",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.5.tgz",
|
||||
"integrity": "sha512-YqUzpisJodwKIlbMFCtyrp58oLloKGnnPLMJ1t23cbfIJjg/H9pvLWK4XS69YeubK5HUs1UE4ys9w5dP1zg6IA==",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
|
||||
"integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
|
||||
"dependencies": {
|
||||
"@types/trusted-types": "^2.0.2"
|
||||
}
|
||||
|
@ -19552,9 +19610,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz",
|
||||
"integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz",
|
||||
"integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
|
@ -19785,9 +19843,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/pyright": {
|
||||
"version": "1.1.319",
|
||||
"resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.319.tgz",
|
||||
"integrity": "sha512-6AC0r2r5rT0BpcPH7S27JS0CpFNKvvfdTRLinWwzeMdJCma9ceF8zUgnvMahHfLUcXn4fyypfth9Dito9tey8g==",
|
||||
"version": "1.1.320",
|
||||
"resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.320.tgz",
|
||||
"integrity": "sha512-YO5GuZTJuSeQBxYPOD+Ih3vfmNcnvc/VafxTG8cObuY5Zu5y+Dq4E0gcdhyGVeg3w29tFL9OvlEO23C6+CjqNw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"pyright": "index.js",
|
||||
|
|
|
@ -34,24 +34,25 @@
|
|||
"@codemirror/legacy-modes": "^6.3.3",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.4.0",
|
||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||
"@fortawesome/fontawesome-free": "^6.4.2",
|
||||
"@goauthentik/api": "^2023.6.1-1690455444",
|
||||
"@lit-labs/context": "^0.3.3",
|
||||
"@lit-labs/task": "^2.1.2",
|
||||
"@lit-labs/task": "^3.0.0",
|
||||
"@lit/localize": "^0.11.4",
|
||||
"@patternfly/elements": "^2.3.2",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.60.1",
|
||||
"@sentry/tracing": "^7.60.1",
|
||||
"@sentry/browser": "^7.61.0",
|
||||
"@sentry/tracing": "^7.61.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.3.2",
|
||||
"chart.js": "^4.3.3",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.32.0",
|
||||
"country-flag-icons": "^1.5.7",
|
||||
"fuse.js": "^6.6.2",
|
||||
"lit": "^2.7.6",
|
||||
"lit": "^2.8.0",
|
||||
"mermaid": "^10.3.0",
|
||||
"rapidoc": "^9.3.4",
|
||||
"style-mod": "^4.0.3",
|
||||
|
@ -85,8 +86,8 @@
|
|||
"@types/chart.js": "^2.9.37",
|
||||
"@types/codemirror": "5.60.8",
|
||||
"@types/grecaptcha": "^3.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
||||
"@typescript-eslint/parser": "^6.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
||||
"@typescript-eslint/parser": "^6.2.1",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"eslint": "^8.46.0",
|
||||
|
@ -96,8 +97,8 @@
|
|||
"eslint-plugin-storybook": "^0.6.13",
|
||||
"lit-analyzer": "^1.2.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.0.0",
|
||||
"pyright": "^1.1.319",
|
||||
"prettier": "^3.0.1",
|
||||
"pyright": "^1.1.320",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"rollup": "^2.79.1",
|
||||
|
|
|
@ -15,6 +15,7 @@ import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
|||
import "@goauthentik/elements/forms/ProxyForm";
|
||||
import "@goauthentik/elements/forms/Radio";
|
||||
import "@goauthentik/elements/forms/SearchSelect";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -158,7 +159,7 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
value=${this.instance?.group}
|
||||
label=${msg("Group")}
|
||||
help=${msg(
|
||||
"Optionally enter a group name. Applications with identical groups are shown grouped together.",
|
||||
"Optionally enter a group name. Applications with identical groups are shown grouped together."
|
||||
)}
|
||||
></ak-text-input>
|
||||
<ak-provider-search-input
|
||||
|
@ -172,11 +173,15 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
name="backchannelProviders"
|
||||
label=${msg("Backchannel Providers")}
|
||||
help=${msg(
|
||||
"Select backchannel providers which augment the functionality of the main provider.",
|
||||
"Select backchannel providers which augment the functionality of the main provider."
|
||||
)}
|
||||
.providers=${this.backchannelProviders}
|
||||
.confirm=${this.handleConfirmBackchannelProviders}
|
||||
.remover=${this.makeRemoveBackchannelProviderHandler}
|
||||
.tooltip=${html`<pf-tooltip
|
||||
position="top"
|
||||
content=${msg("Add provider")}
|
||||
></pf-tooltip>`}
|
||||
>
|
||||
</ak-backchannel-providers-input>
|
||||
<ak-radio-input
|
||||
|
@ -194,7 +199,7 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
label=${msg("Launch URL")}
|
||||
value=${ifDefined(this.instance?.metaLaunchUrl)}
|
||||
help=${msg(
|
||||
"If left empty, authentik will try to extract the launch URL based on the selected provider.",
|
||||
"If left empty, authentik will try to extract the launch URL based on the selected provider."
|
||||
)}
|
||||
></ak-text-input>
|
||||
<ak-switch-input
|
||||
|
@ -202,7 +207,7 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
?checked=${first(this.instance?.openInNewTab, false)}
|
||||
label=${msg("Open in new tab")}
|
||||
help=${msg(
|
||||
"If checked, the launch URL will open in a new browser tab or window from the user's application library.",
|
||||
"If checked, the launch URL will open in a new browser tab or window from the user's application library."
|
||||
)}
|
||||
>
|
||||
</ak-switch-input>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
|||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@goauthentik/user/LibraryApplication/AppIcon";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
|
@ -146,12 +147,16 @@ export class ApplicationListPage extends TablePage<Application> {
|
|||
<ak-application-form slot="form" .instancePk=${item.slug}>
|
||||
</ak-application-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${item.launchUrl
|
||||
? html`<a href=${item.launchUrl} target="_blank" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Open")}>
|
||||
<i class="fas fa-share-square"></i>
|
||||
</pf-tooltip>
|
||||
</a>`
|
||||
: html``}`,
|
||||
];
|
||||
|
|
|
@ -1,60 +1,13 @@
|
|||
import "@goauthentik/admin/applications/ProviderSelectModal";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { TemplateResult, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
import { map } from "lit/directives/map.js";
|
||||
|
||||
import { Provider } from "@goauthentik/api";
|
||||
|
||||
type AkBackchannelProvidersArgs = {
|
||||
// The name of the field, snake-to-camel'd if necessary.
|
||||
name: string;
|
||||
// The label of the field.
|
||||
label: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value?: any;
|
||||
// The help message, shown at the bottom.
|
||||
help?: string;
|
||||
|
||||
providers: Provider[];
|
||||
confirm: ({ items }: { items: Provider[] }) => Promise<void>;
|
||||
remove: (provider: Provider) => () => void;
|
||||
};
|
||||
|
||||
const akBackchannelProvidersDefaults = {
|
||||
required: false,
|
||||
};
|
||||
|
||||
export function akBackchannelProvidersInput(args: AkBackchannelProvidersArgs) {
|
||||
const { name, label, help, providers, confirm, remove } = {
|
||||
...akBackchannelProvidersDefaults,
|
||||
...args,
|
||||
};
|
||||
|
||||
const renderOneChip = (provider: Provider) =>
|
||||
html`<ak-chip .removable=${true} value=${ifDefined(provider.pk)} @remove=${remove(provider)}
|
||||
>${provider.name}</ak-chip
|
||||
>`;
|
||||
|
||||
return html`
|
||||
<ak-form-element-horizontal label=${label} name=${name}>
|
||||
<div class="pf-c-input-group">
|
||||
<ak-provider-select-table ?backchannelOnly=${true} .confirm=${confirm}>
|
||||
<button slot="trigger" class="pf-c-button pf-m-control" type="button">
|
||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</ak-provider-select-table>
|
||||
<div class="pf-c-form-control">
|
||||
<ak-chip-group> ${map(providers, renderOneChip)} </ak-chip-group>
|
||||
</div>
|
||||
</div>
|
||||
${help ? html`<p class="pf-c-form__helper-radio">${help}</p>` : nothing}
|
||||
</ak-form-element-horizontal>
|
||||
`;
|
||||
}
|
||||
|
||||
@customElement("ak-backchannel-providers-input")
|
||||
export class AkBackchannelProvidersInput extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
|
@ -80,6 +33,9 @@ export class AkBackchannelProvidersInput extends AKElement {
|
|||
@property({ type: Array })
|
||||
providers: Provider[] = [];
|
||||
|
||||
@property({ type: Object })
|
||||
tooltip?: TemplateResult;
|
||||
|
||||
@property({ attribute: false, type: Object })
|
||||
confirm!: ({ items }: { items: Provider[] }) => Promise<void>;
|
||||
|
||||
|
@ -96,13 +52,29 @@ export class AkBackchannelProvidersInput extends AKElement {
|
|||
help = "";
|
||||
|
||||
render() {
|
||||
return akBackchannelProvidersInput({
|
||||
name: this.name,
|
||||
label: this.label,
|
||||
help: this.help.trim() !== "" ? this.help : undefined,
|
||||
providers: this.providers,
|
||||
confirm: this.confirm,
|
||||
remove: this.remover,
|
||||
});
|
||||
const renderOneChip = (provider: Provider) =>
|
||||
html`<ak-chip
|
||||
.removable=${true}
|
||||
value=${ifDefined(provider.pk)}
|
||||
@remove=${remove(provider)}
|
||||
>${provider.name}</ak-chip
|
||||
>`;
|
||||
|
||||
return html`
|
||||
<ak-form-element-horizontal label=${label} name=${name}>
|
||||
<div class="pf-c-input-group">
|
||||
<ak-provider-select-table ?backchannelOnly=${true} .confirm=${confirm}>
|
||||
<button slot="trigger" class="pf-c-button pf-m-control" type="button">
|
||||
$ {this.tooltip ? this.tooltip : nothing }
|
||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</ak-provider-select-table>
|
||||
<div class="pf-c-form-control">
|
||||
<ak-chip-group> ${map(providers, renderOneChip)} </ak-chip-group>
|
||||
</div>
|
||||
</div>
|
||||
${help ? html`<p class="pf-c-form__helper-radio">${help}</p>` : nothing}
|
||||
</ak-form-element-horizontal>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -145,9 +146,12 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
|||
<span slot="header"> ${msg("Update Blueprint")} </span>
|
||||
<ak-blueprint-form slot="form" .instancePk=${item.pk}> </ak-blueprint-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</button> </ak-forms-modal
|
||||
><ak-action-button
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-action-button
|
||||
class="pf-m-plain"
|
||||
.apiRequest=${() => {
|
||||
return new ManagedApi(DEFAULT_CONFIG)
|
||||
|
@ -164,7 +168,9 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
|||
});
|
||||
}}
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Apply")}>
|
||||
<i class="fas fa-play" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</ak-action-button>`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -123,7 +124,9 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
|||
<ak-crypto-certificate-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-crypto-certificate-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -10,6 +10,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
|
@ -227,7 +228,9 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
|||
<ak-enterprise-license-form slot="form" .instancePk=${item.licenseUuid}>
|
||||
</ak-enterprise-license-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -6,6 +6,7 @@ import { uiConfig } from "@goauthentik/common/ui/config";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -75,7 +76,9 @@ export class EventListPage extends TablePage<Event> {
|
|||
<small>${EventGeo(item)}</small>`,
|
||||
html`<span>${item.tenant?.name || msg("-")}</span>`,
|
||||
html`<a href="#/events/log/${item.pk}">
|
||||
<pf-tooltip position="top" content=${msg("Show details")}>
|
||||
<i class="fas fa-share-square"></i>
|
||||
</pf-tooltip>
|
||||
</a>`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -91,7 +92,9 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
|||
<span slot="header"> ${msg("Update Notification Rule")} </span>
|
||||
<ak-event-rule-form slot="form" .instancePk=${item.pk}> </ak-event-rule-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -8,6 +8,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -84,7 +85,9 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
|||
<ak-event-transport-form slot="form" .instancePk=${item.pk}>
|
||||
</ak-event-transport-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-action-button
|
||||
|
@ -95,7 +98,9 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
|||
});
|
||||
}}
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Test")}>
|
||||
<i class="fas fa-vial" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</ak-action-button>`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -103,7 +104,9 @@ export class FlowListPage extends TablePage<Flow> {
|
|||
<span slot="header"> ${msg("Update Flow")} </span>
|
||||
<ak-flow-form slot="form" .instancePk=${item.slug}> </ak-flow-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<button
|
||||
|
@ -115,10 +118,14 @@ export class FlowListPage extends TablePage<Flow> {
|
|||
window.open(finalURL, "_blank");
|
||||
}}
|
||||
>
|
||||
<i class="fas fa-play"></i>
|
||||
<pf-tooltip position="top" content=${msg("Execute")}>
|
||||
<i class="fas fa-play" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
<a class="pf-c-button pf-m-plain" href=${item.exportUrl}>
|
||||
<pf-tooltip position="top" content=${msg("Export")}>
|
||||
<i class="fas fa-download"></i>
|
||||
</pf-tooltip>
|
||||
</a>`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -88,7 +89,9 @@ export class GroupListPage extends TablePage<Group> {
|
|||
<span slot="header"> ${msg("Update Group")} </span>
|
||||
<ak-group-form slot="form" .instancePk=${item.pk}> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -11,6 +11,7 @@ import "@goauthentik/elements/forms/HorizontalFormElement";
|
|||
import "@goauthentik/elements/forms/ModalForm";
|
||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -56,7 +57,9 @@ export class RelatedGroupAdd extends Form<{ groups: string[] }> {
|
|||
}}
|
||||
>
|
||||
<button slot="trigger" class="pf-c-button pf-m-control" type="button">
|
||||
<pf-tooltip position="top" content=${msg("Add group")}>
|
||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-user-group-select-table>
|
||||
<div class="pf-c-form-control">
|
||||
|
@ -150,7 +153,9 @@ export class RelatedGroupList extends Table<Group> {
|
|||
<span slot="header"> ${msg("Update Group")} </span>
|
||||
<ak-group-form slot="form" .instancePk=${item.pk}> </ak-group-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -13,6 +13,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult } from "lit";
|
||||
|
@ -135,7 +136,9 @@ export class OutpostListPage extends TablePage<Outpost> {
|
|||
>
|
||||
</ak-outpost-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${item.managed !== "goauthentik.io/outposts/embedded"
|
||||
|
|
|
@ -12,6 +12,7 @@ import "@goauthentik/elements/forms/ProxyForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -99,7 +100,9 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
|
|||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -16,6 +16,7 @@ import "@goauthentik/elements/forms/ProxyForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -86,7 +87,9 @@ export class PolicyListPage extends TablePage<Policy> {
|
|||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-forms-modal .closeAfterSuccessfulSubmit=${false}>
|
||||
|
@ -94,7 +97,9 @@ export class PolicyListPage extends TablePage<Policy> {
|
|||
<span slot="header"> ${msg("Test Policy")} </span>
|
||||
<ak-policy-test-form slot="form" .policy=${item}> </ak-policy-test-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Test")}>
|
||||
<i class="fas fa-vial" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -14,6 +14,7 @@ import { getURLParam, updateURLParams } from "@goauthentik/elements/router/Route
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -101,7 +102,9 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
|||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-forms-modal .closeAfterSuccessfulSubmit=${false}>
|
||||
|
@ -110,7 +113,9 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
|||
<ak-property-mapping-test-form slot="form" .mapping=${item}>
|
||||
</ak-property-mapping-test-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Test")}>
|
||||
<i class="fas fa-vial" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -14,6 +14,7 @@ import "@goauthentik/elements/forms/ProxyForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -118,7 +119,9 @@ export class ProviderListPage extends TablePage<Provider> {
|
|||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -12,6 +12,7 @@ import "@goauthentik/elements/forms/ProxyForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -107,7 +108,9 @@ export class SourceListPage extends TablePage<Source> {
|
|||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -27,6 +27,7 @@ import "@goauthentik/elements/forms/ProxyForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -108,7 +109,9 @@ export class StageListPage extends TablePage<Stage> {
|
|||
>
|
||||
</ak-stage-authenticator-duo-device-import-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<i class="fas fa-file-import"></i>
|
||||
<pf-tooltip position="top" content=${msg("Import devices")}>
|
||||
<i class="fas fa-file-import" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`;
|
||||
default:
|
||||
|
@ -141,7 +144,9 @@ export class StageListPage extends TablePage<Stage> {
|
|||
>
|
||||
</ak-proxy-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${this.renderStageActions(item)}`,
|
||||
|
|
|
@ -10,6 +10,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -127,7 +128,9 @@ export class InvitationListPage extends TablePage<Invitation> {
|
|||
<span slot="header"> ${msg("Update Invitation")} </span>
|
||||
<ak-invitation-form slot="form" .instancePk=${item.pk}> </ak-invitation-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -8,6 +8,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -91,7 +92,9 @@ export class PromptListPage extends TablePage<Prompt> {
|
|||
<span slot="header"> ${msg("Update Prompt")} </span>
|
||||
<ak-prompt-form slot="form" .instancePk=${item.pk}> </ak-prompt-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -6,6 +6,7 @@ import "@goauthentik/elements/buttons/SpinnerButton";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -133,7 +134,9 @@ export class SystemTaskListPage extends TablePage<Task> {
|
|||
});
|
||||
}}
|
||||
>
|
||||
<i class="fas fa-play" aria-hidden="true"></i>
|
||||
<pf-tooltip position="top" content=${msg("Restart task")}>
|
||||
<i class="fas fa-redo" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</ak-action-button>`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -88,7 +89,9 @@ export class TenantListPage extends TablePage<Tenant> {
|
|||
<span slot="header"> ${msg("Update Tenant")} </span>
|
||||
<ak-tenant-form slot="form" .instancePk=${item.tenantUuid}> </ak-tenant-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`,
|
||||
];
|
||||
|
|
|
@ -9,6 +9,7 @@ import "@goauthentik/elements/forms/ModalForm";
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
@ -128,7 +129,9 @@ export class TokenListPage extends TablePage<Token> {
|
|||
<span slot="header"> ${msg("Update Token")} </span>
|
||||
<ak-token-form slot="form" .instancePk=${item.identifier}></ak-token-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>`
|
||||
: html``}
|
||||
|
@ -136,7 +139,9 @@ export class TokenListPage extends TablePage<Token> {
|
|||
class="pf-c-button pf-m-plain"
|
||||
identifier="${item.identifier}"
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Copy token")}>
|
||||
<i class="fas fa-copy"></i>
|
||||
</pf-tooltip>
|
||||
</ak-token-copy-button>
|
||||
`,
|
||||
];
|
||||
|
|
|
@ -20,6 +20,7 @@ import { getURLParam, updateURLParams } from "@goauthentik/elements/router/Route
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { UserOption } from "@goauthentik/elements/user/utils";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -70,7 +71,9 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
|
|||
}}
|
||||
>
|
||||
<button slot="trigger" class="pf-c-button pf-m-control" type="button">
|
||||
<pf-tooltip position="top" content=${msg("Add users")}>
|
||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-group-member-select-table>
|
||||
<div class="pf-c-form-control">
|
||||
|
@ -187,7 +190,9 @@ export class RelatedUserList extends Table<User> {
|
|||
<span slot="header"> ${msg("Update User")} </span>
|
||||
<ak-user-form slot="form" .instancePk=${item.pk}> </ak-user-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${rootInterface()?.config?.capabilities.includes(CapabilitiesEnum.CanImpersonate)
|
||||
|
|
|
@ -20,6 +20,7 @@ import { getURLParam, updateURLParams } from "@goauthentik/elements/router/Route
|
|||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -192,7 +193,9 @@ export class UserListPage extends TablePage<User> {
|
|||
<span slot="header"> ${msg("Update User")} </span>
|
||||
<ak-user-form slot="form" .instancePk=${item.pk}> </ak-user-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<pf-tooltip position="top" content=${msg("Edit")}>
|
||||
<i class="fas fa-edit"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${rootInterface()?.config?.capabilities.includes(CapabilitiesEnum.CanImpersonate)
|
||||
|
|
|
@ -4,7 +4,7 @@ import { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
|
|||
import { adaptCSS } from "@goauthentik/common/utils";
|
||||
|
||||
import { localized } from "@lit/localize";
|
||||
import { LitElement } from "lit";
|
||||
import { CSSResult, LitElement } from "lit";
|
||||
import { state } from "lit/decorators.js";
|
||||
|
||||
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
||||
|
@ -20,6 +20,13 @@ export function rootInterface<T extends Interface>(): T | undefined {
|
|||
return el[0] as T;
|
||||
}
|
||||
|
||||
export function ensureCSSStyleSheet(css: CSSStyleSheet | CSSResult): CSSStyleSheet {
|
||||
if (css instanceof CSSResult) {
|
||||
return css.styleSheet!;
|
||||
}
|
||||
return css;
|
||||
}
|
||||
|
||||
let css: Promise<string[]> | undefined;
|
||||
function fetchCustomCSS(): Promise<string[]> {
|
||||
if (!css) {
|
||||
|
@ -66,7 +73,10 @@ export class AKElement extends LitElement {
|
|||
if ("ShadyDOM" in window) {
|
||||
styleRoot = document;
|
||||
}
|
||||
styleRoot.adoptedStyleSheets = adaptCSS([...styleRoot.adoptedStyleSheets, AKGlobal]);
|
||||
styleRoot.adoptedStyleSheets = adaptCSS([
|
||||
...styleRoot.adoptedStyleSheets,
|
||||
ensureCSSStyleSheet(AKGlobal),
|
||||
]);
|
||||
this._initTheme(styleRoot);
|
||||
this._initCustomCSS(styleRoot);
|
||||
return root;
|
||||
|
@ -151,7 +161,7 @@ export class AKElement extends LitElement {
|
|||
const stylesheet = AKElement.themeToStylesheet(theme);
|
||||
const oldStylesheet = AKElement.themeToStylesheet(this._activeTheme);
|
||||
if (stylesheet) {
|
||||
root.adoptedStyleSheets = [...root.adoptedStyleSheets, stylesheet];
|
||||
root.adoptedStyleSheets = [...root.adoptedStyleSheets, ensureCSSStyleSheet(stylesheet)];
|
||||
}
|
||||
if (oldStylesheet) {
|
||||
root.adoptedStyleSheets = root.adoptedStyleSheets.filter((v) => v !== oldStylesheet);
|
||||
|
@ -173,7 +183,7 @@ export class Interface extends AKElement {
|
|||
|
||||
constructor() {
|
||||
super();
|
||||
document.adoptedStyleSheets = [...document.adoptedStyleSheets, PFBase];
|
||||
document.adoptedStyleSheets = [...document.adoptedStyleSheets, ensureCSSStyleSheet(PFBase)];
|
||||
tenant().then((tenant) => (this.tenant = tenant));
|
||||
config().then((config) => (this.config = config));
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
import { currentInterface } from "@goauthentik/common/sentry";
|
||||
import { me } from "@goauthentik/common/users";
|
||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
|
@ -169,7 +170,9 @@ export class PageHeader extends AKElement {
|
|||
);
|
||||
}}
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Open API drawer")}>
|
||||
<i class="fas fa-code"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
<button
|
||||
class="notification-trigger pf-c-button pf-m-plain ${this.hasNotifications
|
||||
|
@ -184,7 +187,9 @@ export class PageHeader extends AKElement {
|
|||
);
|
||||
}}
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Open Notification drawer")}>
|
||||
<i class="fas fa-bell"></i>
|
||||
</pf-tooltip>
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
|
||||
import PFTooltip from "@patternfly/patternfly/components/Tooltip/tooltip.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
@customElement("ak-tooltip")
|
||||
export class Tooltip extends AKElement {
|
||||
@state()
|
||||
open = false;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
PFBase,
|
||||
PFTooltip,
|
||||
css`
|
||||
.pf-c-tooltip__content {
|
||||
text-align: inherit;
|
||||
}
|
||||
.outer {
|
||||
position: relative;
|
||||
}
|
||||
.pf-c-tooltip {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<slot
|
||||
@mouseenter=${() => {
|
||||
this.open = true;
|
||||
}}
|
||||
@mouseleave=${() => {
|
||||
this.open = false;
|
||||
}}
|
||||
name="trigger"
|
||||
></slot>
|
||||
${this.open
|
||||
? html`<div class="outer">
|
||||
<div class="pf-c-tooltip" role="tooltip">
|
||||
<div class="pf-c-tooltip__arrow"></div>
|
||||
|
||||
<div class="pf-c-tooltip__content">
|
||||
<slot name="tooltip"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
: html``}`;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
|
@ -38,7 +40,9 @@ export class Chip extends AKElement {
|
|||
);
|
||||
}}
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Remove item")}>
|
||||
<i class="fas fa-times" aria-hidden="true"></i>
|
||||
</pf-tooltip>
|
||||
</button>`
|
||||
: html``}
|
||||
</div>
|
||||
|
|
|
@ -99,7 +99,9 @@ export class NotificationDrawer extends AKElement {
|
|||
class="pf-c-dropdown__toggle pf-m-plain"
|
||||
href="/if/admin/#/events/log/${item.event?.pk}"
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Show details")}>
|
||||
<i class="fas fa-share-square"></i>
|
||||
</pf-tooltip>
|
||||
</a>
|
||||
`}
|
||||
<button
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/Tooltip";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
|
@ -19,15 +19,15 @@ export class TimeDeltaHelp extends AKElement {
|
|||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html` <ak-tooltip>
|
||||
<p class="pf-c-form__helper-text" slot="trigger">
|
||||
return html`<div class="pf-c-form__helper-text">
|
||||
<span>
|
||||
${this.negative
|
||||
? msg("(Format: hours=-1;minutes=-2;seconds=-3).")
|
||||
: msg("(Format: hours=1;minutes=2;seconds=3).")}
|
||||
</span>
|
||||
<pf-tooltip position="top">
|
||||
<i class="pf-icon fa fa-question-circle" aria-hidden="true"></i>
|
||||
</p>
|
||||
|
||||
<div slot="tooltip">
|
||||
<div slot="content">
|
||||
${msg("The following keywords are supported:")}
|
||||
<ul class="pf-c-list">
|
||||
<li><pre>microseconds</pre></li>
|
||||
|
@ -39,6 +39,7 @@ export class TimeDeltaHelp extends AKElement {
|
|||
<li><pre>weeks</pre></li>
|
||||
</ul>
|
||||
</div>
|
||||
</ak-tooltip>`;
|
||||
</pf-tooltip>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@ export class FlowErrorStage extends BaseStage<FlowErrorChallenge, FlowChallengeR
|
|||
pre {
|
||||
overflow-x: scroll;
|
||||
max-width: calc(
|
||||
35rem - var(--pf-c-login__main-body--PaddingRight) -
|
||||
var(--pf-c-login__main-body--PaddingRight)
|
||||
35rem - var(--pf-c-login__main-body--PaddingRight) - var(
|
||||
--pf-c-login__main-body--PaddingRight
|
||||
)
|
||||
);
|
||||
}
|
||||
`,
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import type { StoryObj } from "@storybook/web-components";
|
||||
|
||||
import { html } from "lit";
|
||||
|
||||
import "@patternfly/patternfly/components/Login/login.css";
|
||||
|
||||
import { AccessDeniedChallenge, ChallengeChoices, UiThemeEnum } from "@goauthentik/api";
|
||||
|
||||
import "../../../stories/flow-interface";
|
||||
import "./AccessDeniedStage";
|
||||
|
||||
export default {
|
||||
title: "Flow / Stages / AccessDeniedStage",
|
||||
};
|
||||
|
||||
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-access-denied></ak-stage-access-denied>
|
||||
</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-access-denied .challenge=${challenge}></ak-stage-access-denied>
|
||||
</div>
|
||||
</div></div
|
||||
></ak-storybook-interface>`;
|
||||
},
|
||||
args: {
|
||||
theme: "automatic",
|
||||
challenge: {
|
||||
type: ChallengeChoices.Native,
|
||||
pendingUser: "foo",
|
||||
pendingUserAvatar: "https://picsum.photos/64",
|
||||
errorMessage: "This is an error message",
|
||||
} as AccessDeniedChallenge,
|
||||
},
|
||||
argTypes: {
|
||||
theme: {
|
||||
options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
|
||||
control: {
|
||||
type: "select",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,50 +0,0 @@
|
|||
import type { Meta, StoryObj } from "@storybook/web-components";
|
||||
|
||||
import type { ButtonProps } from "./Button";
|
||||
import { Button } from "./Button";
|
||||
|
||||
// More on how to set up stories at: https://storybook.js.org/docs/web-components/writing-stories/introduction
|
||||
const meta = {
|
||||
title: "Example/Button",
|
||||
tags: ["autodocs"],
|
||||
render: (args) => Button(args),
|
||||
argTypes: {
|
||||
backgroundColor: { control: "color" },
|
||||
onClick: { action: "onClick" },
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: ["small", "medium", "large"],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<ButtonProps>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<ButtonProps>;
|
||||
|
||||
// More on writing stories with args: https://storybook.js.org/docs/web-components/writing-stories/args
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
primary: true,
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const Large: Story = {
|
||||
args: {
|
||||
size: "large",
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
size: "small",
|
||||
label: "Button",
|
||||
},
|
||||
};
|
|
@ -1,44 +0,0 @@
|
|||
import { html } from "lit";
|
||||
import { styleMap } from "lit/directives/style-map.js";
|
||||
|
||||
import "./button.css";
|
||||
|
||||
export interface ButtonProps {
|
||||
/**
|
||||
* Is this the principal call to action on the page?
|
||||
*/
|
||||
primary?: boolean;
|
||||
/**
|
||||
* What background color to use
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* How large should the button be?
|
||||
*/
|
||||
size?: "small" | "medium" | "large";
|
||||
/**
|
||||
* Button contents
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Optional click handler
|
||||
*/
|
||||
onClick?: () => void;
|
||||
}
|
||||
/**
|
||||
* Primary UI component for user interaction
|
||||
*/
|
||||
export const Button = ({ primary, backgroundColor, size, label, onClick }: ButtonProps) => {
|
||||
const mode = primary ? "storybook-button--primary" : "storybook-button--secondary";
|
||||
|
||||
return html`
|
||||
<button
|
||||
type="button"
|
||||
class=${["storybook-button", `storybook-button--${size || "medium"}`, mode].join(" ")}
|
||||
style=${styleMap({ backgroundColor })}
|
||||
@click=${onClick}
|
||||
>
|
||||
${label}
|
||||
</button>
|
||||
`;
|
||||
};
|
|
@ -1,24 +0,0 @@
|
|||
import type { Meta, StoryObj } from "@storybook/web-components";
|
||||
|
||||
import type { HeaderProps } from "./Header";
|
||||
import { Header } from "./Header";
|
||||
|
||||
const meta = {
|
||||
title: "Example/Header",
|
||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/web-components/writing-docs/autodocs
|
||||
tags: ["autodocs"],
|
||||
render: (args: HeaderProps) => Header(args),
|
||||
} satisfies Meta<HeaderProps>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<HeaderProps>;
|
||||
|
||||
export const LoggedIn: Story = {
|
||||
args: {
|
||||
user: {
|
||||
name: "Jane Doe",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const LoggedOut: Story = {};
|
|
@ -1,57 +0,0 @@
|
|||
import { html } from "lit";
|
||||
|
||||
import "./header.css";
|
||||
|
||||
import { Button } from "./Button";
|
||||
|
||||
type User = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export interface HeaderProps {
|
||||
user?: User;
|
||||
onLogin: () => void;
|
||||
onLogout: () => void;
|
||||
onCreateAccount: () => void;
|
||||
}
|
||||
|
||||
export const Header = ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps) => html`
|
||||
<header>
|
||||
<div class="storybook-header">
|
||||
<div>
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
|
||||
fill="#FFF"
|
||||
/>
|
||||
<path
|
||||
d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
|
||||
fill="#555AB9"
|
||||
/>
|
||||
<path
|
||||
d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z"
|
||||
fill="#91BAF8"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
<h1>Acme</h1>
|
||||
</div>
|
||||
<div>
|
||||
${user
|
||||
? Button({ size: "small", onClick: onLogout, label: "Log out" })
|
||||
: html`${Button({
|
||||
size: "small",
|
||||
onClick: onLogin,
|
||||
label: "Log in",
|
||||
})}
|
||||
${Button({
|
||||
primary: true,
|
||||
size: "small",
|
||||
onClick: onCreateAccount,
|
||||
label: "Sign up",
|
||||
})}`}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
`;
|
|
@ -1,214 +0,0 @@
|
|||
import { Meta } from "@storybook/blocks";
|
||||
|
||||
import Code from "./assets/code-brackets.svg";
|
||||
import Colors from "./assets/colors.svg";
|
||||
import Comments from "./assets/comments.svg";
|
||||
import Direction from "./assets/direction.svg";
|
||||
import Flow from "./assets/flow.svg";
|
||||
import Plugin from "./assets/plugin.svg";
|
||||
import Repo from "./assets/repo.svg";
|
||||
import StackAlt from "./assets/stackalt.svg";
|
||||
|
||||
<Meta title="Example/Introduction" />
|
||||
|
||||
<style>
|
||||
{`
|
||||
.subheading {
|
||||
--mediumdark: '#999999';
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
letter-spacing: 6px;
|
||||
line-height: 24px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.link-list {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
row-gap: 10px;
|
||||
}
|
||||
|
||||
@media (min-width: 620px) {
|
||||
.link-list {
|
||||
row-gap: 20px;
|
||||
column-gap: 20px;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (-ms-high-contrast:none) {
|
||||
.link-list {
|
||||
display: -ms-grid;
|
||||
-ms-grid-columns: 1fr 1fr;
|
||||
-ms-grid-rows: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.link-item {
|
||||
display: block;
|
||||
padding: 20px;
|
||||
border: 1px solid #00000010;
|
||||
border-radius: 5px;
|
||||
transition: background 150ms ease-out, border 150ms ease-out, transform 150ms ease-out;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.link-item:hover {
|
||||
border-color: #1EA7FD50;
|
||||
transform: translate3d(0, -3px, 0);
|
||||
box-shadow: rgba(0, 0, 0, 0.08) 0 3px 10px 0;
|
||||
}
|
||||
|
||||
.link-item:active {
|
||||
border-color: #1EA7FD;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.link-item strong {
|
||||
font-weight: 700;
|
||||
display: block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.link-item img {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
margin-right: 15px;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.link-item span,
|
||||
.link-item p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
display: inline-block;
|
||||
border-radius: 1em;
|
||||
font-size: 11px;
|
||||
line-height: 12px;
|
||||
font-weight: 700;
|
||||
background: #E7FDD8;
|
||||
color: #66BF3C;
|
||||
padding: 4px 12px;
|
||||
margin-right: 10px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.tip-wrapper {
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.tip-wrapper code {
|
||||
font-size: 12px;
|
||||
display: inline-block;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
# Welcome to Storybook
|
||||
|
||||
Storybook helps you build UI components in isolation from your app's business logic, data, and context.
|
||||
That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.
|
||||
|
||||
Browse example stories now by navigating to them in the sidebar.
|
||||
View their code in the `stories` directory to learn how they work.
|
||||
We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages.
|
||||
|
||||
<div className="subheading">Configure</div>
|
||||
|
||||
<div className="link-list">
|
||||
<a
|
||||
className="link-item"
|
||||
href="https://storybook.js.org/docs/react/addons/addon-types"
|
||||
target="_blank"
|
||||
>
|
||||
<img src={Plugin} alt="plugin" />
|
||||
<span>
|
||||
<strong>Presets for popular tools</strong>
|
||||
Easy setup for TypeScript, SCSS and more.
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="link-item"
|
||||
href="https://storybook.js.org/docs/react/configure/webpack"
|
||||
target="_blank"
|
||||
>
|
||||
<img src={StackAlt} alt="Build" />
|
||||
<span>
|
||||
<strong>Build configuration</strong>
|
||||
How to customize webpack and Babel
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="link-item"
|
||||
href="https://storybook.js.org/docs/react/configure/styling-and-css"
|
||||
target="_blank"
|
||||
>
|
||||
<img src={Colors} alt="colors" />
|
||||
<span>
|
||||
<strong>Styling</strong>
|
||||
How to load and configure CSS libraries
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
className="link-item"
|
||||
href="https://storybook.js.org/docs/react/get-started/setup#configure-storybook-for-your-stack"
|
||||
target="_blank"
|
||||
>
|
||||
<img src={Flow} alt="flow" />
|
||||
<span>
|
||||
<strong>Data</strong>
|
||||
Providers and mocking for data libraries
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="subheading">Learn</div>
|
||||
|
||||
<div className="link-list">
|
||||
<a className="link-item" href="https://storybook.js.org/docs" target="_blank">
|
||||
<img src={Repo} alt="repo" />
|
||||
<span>
|
||||
<strong>Storybook documentation</strong>
|
||||
Configure, customize, and extend
|
||||
</span>
|
||||
</a>
|
||||
<a className="link-item" href="https://storybook.js.org/tutorials/" target="_blank">
|
||||
<img src={Direction} alt="direction" />
|
||||
<span>
|
||||
<strong>In-depth guides</strong>
|
||||
Best practices from leading teams
|
||||
</span>
|
||||
</a>
|
||||
<a className="link-item" href="https://github.com/storybookjs/storybook" target="_blank">
|
||||
<img src={Code} alt="code" />
|
||||
<span>
|
||||
<strong>GitHub project</strong>
|
||||
View the source and add issues
|
||||
</span>
|
||||
</a>
|
||||
<a className="link-item" href="https://discord.gg/storybook" target="_blank">
|
||||
<img src={Comments} alt="comments" />
|
||||
<span>
|
||||
<strong>Discord chat</strong>
|
||||
Chat with maintainers and the community
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="tip-wrapper">
|
||||
<span className="tip">Tip</span>Edit the Markdown in{" "}
|
||||
<code>stories/Introduction.stories.mdx</code>
|
||||
</div>
|
|
@ -1,26 +0,0 @@
|
|||
import type { Meta, StoryObj } from "@storybook/web-components";
|
||||
|
||||
import * as HeaderStories from "./Header.stories";
|
||||
import type { PageProps } from "./Page";
|
||||
import { Page } from "./Page";
|
||||
|
||||
const meta = {
|
||||
title: "Example/Page",
|
||||
render: (args: PageProps) => Page(args),
|
||||
} satisfies Meta<PageProps>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<PageProps>;
|
||||
|
||||
export const LoggedIn: Story = {
|
||||
args: {
|
||||
// More on composing args: https://storybook.js.org/docs/web-components/writing-stories/args#args-composition
|
||||
...HeaderStories.LoggedIn.args,
|
||||
},
|
||||
};
|
||||
|
||||
export const LoggedOut: Story = {
|
||||
args: {
|
||||
...HeaderStories.LoggedOut.args,
|
||||
},
|
||||
};
|
|
@ -1,80 +0,0 @@
|
|||
import { html } from "lit";
|
||||
|
||||
import "./page.css";
|
||||
|
||||
import { Header } from "./Header";
|
||||
|
||||
type User = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export interface PageProps {
|
||||
user?: User;
|
||||
onLogin: () => void;
|
||||
onLogout: () => void;
|
||||
onCreateAccount: () => void;
|
||||
}
|
||||
|
||||
export const Page = ({ user, onLogin, onLogout, onCreateAccount }: PageProps) => html`
|
||||
<article>
|
||||
${Header({
|
||||
user,
|
||||
onLogin,
|
||||
onLogout,
|
||||
onCreateAccount,
|
||||
})}
|
||||
|
||||
<section class="storybook-page">
|
||||
<h2>Pages in Storybook</h2>
|
||||
<p>
|
||||
We recommend building UIs with a
|
||||
<a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
|
||||
<strong>component-driven</strong> </a
|
||||
>process starting with atomic components and ending with pages.
|
||||
</p>
|
||||
<p>
|
||||
Render pages with mock data. This makes it easy to build and review page states
|
||||
without needing to navigate to them in your app. Here are some handy patterns for
|
||||
managing page data in Storybook:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Use a higher-level connected component. Storybook helps you compose such data
|
||||
from the "args" of child component stories
|
||||
</li>
|
||||
<li>
|
||||
Assemble data in the page component from your services. You can mock these
|
||||
services out using Storybook.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Get a guided tutorial on component-driven development at
|
||||
<a
|
||||
href="https://storybook.js.org/tutorials/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Storybook tutorials
|
||||
</a>
|
||||
. Read more in the
|
||||
<a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">
|
||||
docs
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<div class="tip-wrapper">
|
||||
<span class="tip">Tip</span> Adjust the width of the canvas with the
|
||||
<svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
|
||||
id="a"
|
||||
fill="#999"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
Viewports addon in the toolbar
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
`;
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48" version="1.1" viewBox="0 0 48 48"><title>illustration/code-brackets</title><g id="illustration/code-brackets" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><path id="Combined-Shape" fill="#87E6E5" d="M11.4139325,12 C11.7605938,12 12,12.5059743 12,13.3779712 L12,17.4951758 L6.43502246,23.3839989 C5.85499251,23.9978337 5.85499251,25.0021663 6.43502246,25.6160011 L12,31.5048242 L12,35.6220288 C12,36.4939606 11.7605228,37 11.4139325,37 C11.2725831,37 11.1134406,36.9158987 10.9453839,36.7379973 L0.435022463,25.6160011 C-0.145007488,25.0021663 -0.145007488,23.9978337 0.435022463,23.3839989 L10.9453839,12.2620027 C11.1134051,12.0841663 11.2725831,12 11.4139325,12 Z M36.5860675,12 C36.7274169,12 36.8865594,12.0841013 37.0546161,12.2620027 L47.5649775,23.3839989 C48.1450075,23.9978337 48.1450075,25.0021663 47.5649775,25.6160011 L37.0546161,36.7379973 C36.8865949,36.9158337 36.7274169,37 36.5860675,37 C36.2394062,37 36,36.4940257 36,35.6220288 L36,31.5048242 L41.5649775,25.6160011 C42.1450075,25.0021663 42.1450075,23.9978337 41.5649775,23.3839989 L36,17.4951758 L36,13.3779712 C36,12.5060394 36.2394772,12 36.5860675,12 Z"/><rect id="Rectangle-7-Copy-5" width="35.57" height="4" x="5.009" y="22.662" fill="#A0DB77" rx="2" transform="translate(22.793959, 24.662305) rotate(-75.000000) translate(-22.793959, -24.662305)"/></g></svg>
|
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 8.3 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48" version="1.1" viewBox="0 0 48 48"><title>illustration/comments</title><g id="illustration/comments" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><path id="Path" fill="#96D07C" d="M2.52730803,17.9196415 C2.44329744,17.9745167 2.36370847,18.000488 2.29303375,18.000488 C2.1197031,18.000488 2,17.8443588 2,17.5752855 L2,4 C2,1.790861 3.790861,3.23296945e-13 6,3.23296945e-13 L33.9995117,3.23296945e-13 C36.2086507,3.23296945e-13 37.9995117,1.790861 37.9995117,4 L37.9995117,9.999512 C37.9995117,12.208651 36.2086507,13.999512 33.9995117,13.999512 L8,13.999512 C7.83499225,13.999512 7.6723181,13.9895206 7.51254954,13.9701099 L2.52730803,17.9196415 Z"/><path id="Path" fill="#73E1E0" d="M7.51066,44.9703679 L2.52730803,47.9186655 C2.44329744,47.9735407 2.36370847,47.999512 2.29303375,47.999512 C2.1197031,47.999512 2,47.8433828 2,47.5743095 L2,35 C2,32.790861 3.790861,31 6,31 L26,31 C28.209139,31 30,32.790861 30,35 L30,41 C30,43.209139 28.209139,45 26,45 L8,45 C7.8343417,45 7.67103544,44.9899297 7.51066,44.9703679 Z"/><path id="Path" fill="#FFD476" d="M46,19.5 L46,33.0747975 C46,33.3438708 45.8802969,33.5 45.7069663,33.5 C45.6362915,33.5 45.5567026,33.4740287 45.472692,33.4191535 L40.4887103,29.4704446 C40.3285371,29.489956 40.1654415,29.5 40,29.5 L18,29.5 C15.790861,29.5 14,27.709139 14,25.5 L14,19.5 C14,17.290861 15.790861,15.5 18,15.5 L42,15.5 C44.209139,15.5 46,17.290861 46,19.5 Z"/></g></svg>
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48" version="1.1" viewBox="0 0 48 48"><title>illustration/direction</title><g id="illustration/direction" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><path id="Combined-Shape" fill="#FFD476" d="M23.4917015,33.6030641 L2.93840258,31.4321033 C2.38917316,31.3740904 1.99096346,30.8818233 2.04897631,30.3325939 C2.0747515,30.0885705 2.18934861,29.8625419 2.37095722,29.6975265 L34.2609105,0.721285325 C34.6696614,0.349881049 35.3021022,0.38015648 35.6735064,0.788907393 C35.9232621,1.06377731 36.0001133,1.45442096 35.8730901,1.80341447 L24.5364357,32.9506164 C24.3793473,33.3822133 23.9484565,33.6513092 23.4917015,33.6030641 L23.4917015,33.6030641 Z"/><path id="Combined-Shape-Copy" fill="#FFC445" d="M24.3163597,33.2881029 C24.0306575,33.0138462 23.9337246,32.5968232 24.069176,32.2246735 L35.091923,1.9399251 C35.2266075,1.56988243 35.5659249,1.31333613 35.9586669,1.28460955 C36.5094802,1.24432106 36.9886628,1.65818318 37.0289513,2.20899647 L40.2437557,46.1609256 C40.2644355,46.4436546 40.1641446,46.7218752 39.9678293,46.9263833 C39.5853672,47.3248067 38.9523344,47.3377458 38.5539111,46.9552837 L24.3163597,33.2881029 L24.3163597,33.2881029 Z"/></g></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48" version="1.1" viewBox="0 0 48 48"><title>illustration/flow</title><g id="illustration/flow" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><path id="Combined-Shape" fill="#79C9FC" fill-rule="nonzero" d="M30,29 C32.7614237,29 35,26.7614237 35,24 C35,14.6111593 27.3888407,7 18,7 C8.61115925,7 1,14.6111593 1,24 C1,33.3888407 8.61115925,41 18,41 C19.3333404,41 20.6447683,40.8466238 21.9154603,40.5471706 C19.5096374,39.3319645 17.5510566,37.8612875 16.0456579,36.1314815 C14.1063138,33.9030427 12.769443,31.0725999 12.0293806,27.6556449 C11.360469,26.565281 11,25.3082308 11,24 C11,20.1340068 14.1340068,17 18,17 C21.8659932,17 25,20.1340068 25,24 C25,26.125 27.7040312,29 30,29 Z"/><path id="Combined-Shape-Copy" fill="#FFC445" fill-rule="nonzero" d="M42,29 C44.7614237,29 47,26.7614237 47,24 C47,14.6111593 39.3888407,7 30,7 C20.6111593,7 13,14.6111593 13,24 C13,33.3888407 20.6111593,41 30,41 C31.3333404,41 32.6447683,40.8466238 33.9154603,40.5471706 C31.5096374,39.3319645 29.4051056,37.9781963 28.0456579,36.1314815 C26.0625,33.4375 23,27.1875 23,24 C23,20.1340068 26.1340068,17 30,17 C33.8659932,17 37,20.1340068 37,24 C37.02301,26.3435241 39.7040312,29 42,29 Z" transform="translate(30.000000, 24.000000) scale(-1, -1) translate(-30.000000, -24.000000)"/></g></svg>
|
Before Width: | Height: | Size: 1.4 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48" version="1.1" viewBox="0 0 48 48"><title>illustration/plugin</title><g id="illustration/plugin" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><path id="Combined-Shape" fill="#79C9FC" d="M26,15.3994248 C26,15.4091303 26,15.4188459 26,15.4285714 L26,21.4694881 C25.8463595,21.4969567 25.6941676,21.51275 25.5873784,21.51275 C25.4974117,21.51275 25.4230979,21.4768034 25.377756,21.4206259 L25.2660784,21.2822603 L25.1317423,21.1657666 C24.2436317,20.3956144 23.100098,19.9633214 21.895551,19.9633214 C19.2039137,19.9633214 17,22.1075558 17,24.7804643 C17,27.4533728 19.2039137,29.5976071 21.895551,29.5976071 C23.1972122,29.5976071 24.3149423,29.2878193 25.1231445,28.3613697 C25.4542273,27.9818463 25.568273,27.9073214 25.5873784,27.9073214 C25.681532,27.9073214 25.8352452,27.9239643 26,27.9524591 L26,32.5714286 C26,32.5811541 26,32.5908697 26,32.6005752 L26,33 C26,35.209139 24.209139,37 22,37 L4,37 C1.790861,37 0,35.209139 0,33 L0,15 C0,12.790861 1.790861,11 4,11 L22,11 C24.209139,11 26,12.790861 26,15 L26,15.3994248 Z"/><path id="Path" fill="#87E6E5" d="M27.9998779,32.5714286 C27.9998779,33.3604068 28.6572726,34 29.4682101,34 L46.5315458,34 C47.3424832,34 47.9998779,33.3604068 47.9998779,32.5714286 L47.9998779,15.4285714 C47.9998779,14.6395932 47.3424832,14 46.5315458,14 L29.4682101,14 C28.6572726,14 27.9998779,14.6395932 27.9998779,15.4285714 L27.9998779,21.8355216 C27.9334367,22.2650514 27.8567585,22.6454496 27.746391,22.8084643 C27.4245309,23.2838571 26.2402709,23.51275 25.5873784,23.51275 C24.8705773,23.51275 24.2322714,23.1857725 23.8214379,22.6767605 C23.3096996,22.2329909 22.6349941,21.9633214 21.895551,21.9633214 C20.2963823,21.9633214 19,23.2245992 19,24.7804643 C19,26.3363293 20.2963823,27.5976071 21.895551,27.5976071 C22.5398535,27.5976071 23.2399343,27.477727 23.6160247,27.0466112 C24.1396029,26.4464286 24.7367044,25.9073214 25.5873784,25.9073214 C26.2402709,25.9073214 27.5912951,26.1766031 27.8226692,26.6116071 C27.8819199,26.7230038 27.9403239,26.921677 27.9998779,27.1556219 L27.9998779,32.5714286 Z"/></g></svg>
|
Before Width: | Height: | Size: 2.1 KiB |