Merge branch 'main' into web/theme-controller-2

* main:
  web: bump API Client version (#7246)
  sources/oauth: include default JWKS URLs for OAuth sources (#6992)
  sources/oauth: periodically update OAuth sources' OIDC configuration (#7245)
  website/blogs: Fix sso blog to remove 3rd reason (#7230)
  lifecycle: fix otp_merge migration again (#7244)
  web: bump core-js from 3.33.0 to 3.33.1 in /web (#7243)
  core: bump node from 20 to 21 (#7237)
  web: fix bad comment that was confusing lit-analyze (#7234)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7235)
  core: bump ruff from 0.1.0 to 0.1.1 (#7238)
  core: bump twilio from 8.9.1 to 8.10.0 (#7239)
  web: bump the storybook group in /web with 5 updates (#7240)
  web: bump the wdio group in /tests/wdio with 4 updates (#7241)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7236)
  web: isolate clipboard handling (#7229)
This commit is contained in:
Ken Sternberg 2023-10-20 08:28:00 -07:00
commit e8edbdb4ae
25 changed files with 1433 additions and 1501 deletions

View File

@ -1,5 +1,5 @@
# Stage 1: Build website
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as website-builder
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as website-builder
ENV NODE_ENV=production
@ -17,7 +17,7 @@ COPY ./SECURITY.md /work/
RUN npm run build-docs-only
# Stage 2: Build webui
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as web-builder
ENV NODE_ENV=production

View File

@ -30,6 +30,8 @@ class SourceTypeSerializer(PassiveSerializer):
authorization_url = CharField(read_only=True, allow_null=True)
access_token_url = CharField(read_only=True, allow_null=True)
profile_url = CharField(read_only=True, allow_null=True)
oidc_well_known_url = CharField(read_only=True, allow_null=True)
oidc_jwks_url = CharField(read_only=True, allow_null=True)
class OAuthSourceSerializer(SourceSerializer):
@ -56,7 +58,11 @@ class OAuthSourceSerializer(SourceSerializer):
def validate(self, attrs: dict) -> dict:
session = get_http_session()
well_known = attrs.get("oidc_well_known_url")
source_type = registry.find_type(attrs["provider_type"])
well_known = attrs.get("oidc_well_known_url") or source_type.oidc_well_known_url
inferred_oidc_jwks_url = None
if well_known and well_known != "":
try:
well_known_config = session.get(well_known)
@ -69,20 +75,22 @@ class OAuthSourceSerializer(SourceSerializer):
attrs["authorization_url"] = config["authorization_endpoint"]
attrs["access_token_url"] = config["token_endpoint"]
attrs["profile_url"] = config["userinfo_endpoint"]
attrs["oidc_jwks_url"] = config["jwks_uri"]
inferred_oidc_jwks_url = config["jwks_uri"]
except (IndexError, KeyError) as exc:
raise ValidationError(
{"oidc_well_known_url": f"Invalid well-known configuration: {exc}"}
)
jwks_url = attrs.get("oidc_jwks_url")
# Prefer user-entered URL to inferred URL to default URL
jwks_url = attrs.get("oidc_jwks_url") or inferred_oidc_jwks_url or source_type.oidc_jwks_url
if jwks_url and jwks_url != "":
attrs["oidc_jwks_url"] = jwks_url
try:
jwks_config = session.get(jwks_url)
jwks_config.raise_for_status()
except RequestException as exc:
text = exc.response.text if exc.response else str(exc)
raise ValidationError({"jwks_url": text})
raise ValidationError({"oidc_jwks_url": text})
config = jwks_config.json()
attrs["oidc_jwks"] = config

View File

@ -0,0 +1,12 @@
"""OAuth source settings"""
from celery.schedules import crontab
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"update_oauth_source_oidc_well_known": {
"task": "authentik.sources.oauth.tasks.update_well_known_jwks",
"schedule": crontab(minute=fqdn_rand("update_well_known_jwks"), hour="*/3"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -0,0 +1,70 @@
"""OAuth Source tasks"""
from json import dumps
from requests import RequestException
from structlog.stdlib import get_logger
from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus
from authentik.lib.utils.http import get_http_session
from authentik.root.celery import CELERY_APP
from authentik.sources.oauth.models import OAuthSource
LOGGER = get_logger()
@CELERY_APP.task(bind=True, base=MonitoredTask)
def update_well_known_jwks(self: MonitoredTask):
"""Update OAuth sources' config from well_known, and JWKS info from the configured URL"""
session = get_http_session()
result = TaskResult(TaskResultStatus.SUCCESSFUL, [])
for source in OAuthSource.objects.all().exclude(oidc_well_known_url=""):
try:
well_known_config = session.get(source.oidc_well_known_url)
well_known_config.raise_for_status()
except RequestException as exc:
text = exc.response.text if exc.response else str(exc)
LOGGER.warning("Failed to update well_known", source=source, exc=exc, text=text)
result.messages.append(f"Failed to update OIDC configuration for {source.slug}")
continue
config = well_known_config.json()
try:
dirty = False
source_attr_key = (
("authorization_url", "authorization_endpoint"),
("access_token_url", "token_endpoint"),
("profile_url", "userinfo_endpoint"),
("oidc_jwks_url", "jwks_uri"),
)
for source_attr, config_key in source_attr_key:
# Check if we're actually changing anything to only
# save when something has changed
if getattr(source, source_attr) != config[config_key]:
dirty = True
setattr(source, source_attr, config[config_key])
except (IndexError, KeyError) as exc:
LOGGER.warning(
"Failed to update well_known",
source=source,
exc=exc,
)
result.messages.append(f"Failed to update OIDC configuration for {source.slug}")
continue
if dirty:
LOGGER.info("Updating sources' OpenID Configuration", source=source)
source.save()
for source in OAuthSource.objects.all().exclude(oidc_jwks_url=""):
try:
jwks_config = session.get(source.oidc_jwks_url)
jwks_config.raise_for_status()
except RequestException as exc:
text = exc.response.text if exc.response else str(exc)
LOGGER.warning("Failed to update JWKS", source=source, exc=exc, text=text)
result.messages.append(f"Failed to update JWKS for {source.slug}")
continue
config = jwks_config.json()
if dumps(source.oidc_jwks, sort_keys=True) != dumps(config, sort_keys=True):
source.oidc_jwks = config
LOGGER.info("Updating sources' JWKS", source=source)
source.save()
self.set_status(result)

View File

@ -0,0 +1,48 @@
"""Test OAuth Source tasks"""
from django.test import TestCase
from requests_mock import Mocker
from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.tasks import update_well_known_jwks
class TestOAuthSourceTasks(TestCase):
"""Test OAuth Source tasks"""
def setUp(self) -> None:
self.source = OAuthSource.objects.create(
name="test",
slug="test",
provider_type="openidconnect",
authorization_url="",
profile_url="",
consumer_key="",
)
@Mocker()
def test_well_known_jwks(self, mock: Mocker):
"""Test well_known update"""
self.source.oidc_well_known_url = "http://foo/.well-known/openid-configuration"
self.source.save()
mock.get(
self.source.oidc_well_known_url,
json={
"authorization_endpoint": "foo",
"token_endpoint": "foo",
"userinfo_endpoint": "foo",
"jwks_uri": "http://foo/jwks",
},
)
mock.get("http://foo/jwks", json={"foo": "bar"})
update_well_known_jwks() # pylint: disable=no-value-for-parameter
self.source.refresh_from_db()
self.assertEqual(self.source.authorization_url, "foo")
self.assertEqual(self.source.access_token_url, "foo")
self.assertEqual(self.source.profile_url, "foo")
self.assertEqual(self.source.oidc_jwks_url, "http://foo/jwks")
self.assertEqual(
self.source.oidc_jwks,
{
"foo": "bar",
},
)

View File

@ -51,3 +51,7 @@ class AzureADType(SourceType):
authorization_url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
access_token_url = "https://login.microsoftonline.com/common/oauth2/v2.0/token" # nosec
profile_url = "https://graph.microsoft.com/v1.0/me"
oidc_well_known_url = (
"https://login.microsoftonline.com/common/.well-known/openid-configuration"
)
oidc_jwks_url = "https://login.microsoftonline.com/common/discovery/keys"

View File

@ -76,3 +76,7 @@ class GitHubType(SourceType):
authorization_url = "https://github.com/login/oauth/authorize"
access_token_url = "https://github.com/login/oauth/access_token" # nosec
profile_url = "https://api.github.com/user"
oidc_well_known_url = (
"https://token.actions.githubusercontent.com/.well-known/openid-configuration"
)
oidc_jwks_url = "https://token.actions.githubusercontent.com/.well-known/jwks"

View File

@ -40,3 +40,5 @@ class GoogleType(SourceType):
authorization_url = "https://accounts.google.com/o/oauth2/auth"
access_token_url = "https://oauth2.googleapis.com/token" # nosec
profile_url = "https://www.googleapis.com/oauth2/v1/userinfo"
oidc_well_known_url = "https://accounts.google.com/.well-known/openid-configuration"
oidc_jwks_url = "https://www.googleapis.com/oauth2/v3/certs"

View File

@ -36,6 +36,8 @@ class SourceType:
authorization_url: Optional[str] = None
access_token_url: Optional[str] = None
profile_url: Optional[str] = None
oidc_well_known_url: Optional[str] = None
oidc_jwks_url: Optional[str] = None
def icon_url(self) -> str:
"""Get Icon URL for login"""

View File

@ -23,7 +23,6 @@ class Migration(BaseMigration):
return bool(self.cur.rowcount)
def run(self):
with self.con.transaction():
self.cur.execute(SQL_STATEMENT)
self.fake_migration(
(

42
poetry.lock generated
View File

@ -3421,28 +3421,28 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.1.0"
version = "0.1.1"
description = "An extremely fast Python linter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.1.0-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:87114e254dee35e069e1b922d85d4b21a5b61aec759849f393e1dbb308a00439"},
{file = "ruff-0.1.0-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:764f36d2982cc4a703e69fb73a280b7c539fd74b50c9ee531a4e3fe88152f521"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65f4b7fb539e5cf0f71e9bd74f8ddab74cabdd673c6fb7f17a4dcfd29f126255"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:299fff467a0f163baa282266b310589b21400de0a42d8f68553422fa6bf7ee01"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d412678bf205787263bb702c984012a4f97e460944c072fd7cfa2bd084857c4"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a5391b49b1669b540924640587d8d24128e45be17d1a916b1801d6645e831581"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee8cd57f454cdd77bbcf1e11ff4e0046fb6547cac1922cc6e3583ce4b9c326d1"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa7aeed7bc23861a2b38319b636737bf11cfa55d2109620b49cf995663d3e888"},
{file = "ruff-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04cd4298b43b16824d9a37800e4c145ba75c29c43ce0d74cad1d66d7ae0a4c5"},
{file = "ruff-0.1.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7186ccf54707801d91e6314a016d1c7895e21d2e4cd614500d55870ed983aa9f"},
{file = "ruff-0.1.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d88adfd93849bc62449518228581d132e2023e30ebd2da097f73059900d8dce3"},
{file = "ruff-0.1.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ad2ccdb3bad5a61013c76a9c1240fdfadf2c7103a2aeebd7bcbbed61f363138f"},
{file = "ruff-0.1.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b77f6cfa72c6eb19b5cac967cc49762ae14d036db033f7d97a72912770fd8e1c"},
{file = "ruff-0.1.0-py3-none-win32.whl", hash = "sha256:480bd704e8af1afe3fd444cc52e3c900b936e6ca0baf4fb0281124330b6ceba2"},
{file = "ruff-0.1.0-py3-none-win_amd64.whl", hash = "sha256:a76ba81860f7ee1f2d5651983f87beb835def94425022dc5f0803108f1b8bfa2"},
{file = "ruff-0.1.0-py3-none-win_arm64.whl", hash = "sha256:45abdbdab22509a2c6052ecf7050b3f5c7d6b7898dc07e82869401b531d46da4"},
{file = "ruff-0.1.0.tar.gz", hash = "sha256:ad6b13824714b19c5f8225871cf532afb994470eecb74631cd3500fe817e6b3f"},
{file = "ruff-0.1.1-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:b7cdc893aef23ccc14c54bd79a8109a82a2c527e11d030b62201d86f6c2b81c5"},
{file = "ruff-0.1.1-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:620d4b34302538dbd8bbbe8fdb8e8f98d72d29bd47e972e2b59ce6c1e8862257"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a909d3930afdbc2e9fd893b0034479e90e7981791879aab50ce3d9f55205bd6"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3305d1cb4eb8ff6d3e63a48d1659d20aab43b49fe987b3ca4900528342367145"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c34ae501d0ec71acf19ee5d4d889e379863dcc4b796bf8ce2934a9357dc31db7"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6aa7e63c3852cf8fe62698aef31e563e97143a4b801b57f920012d0e07049a8d"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2d68367d1379a6b47e61bc9de144a47bcdb1aad7903bbf256e4c3d31f11a87ae"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc11955f6ce3398d2afe81ad7e49d0ebf0a581d8bcb27b8c300281737735e3a3"},
{file = "ruff-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbd8eead88ea83a250499074e2a8e9d80975f0b324b1e2e679e4594da318c25"},
{file = "ruff-0.1.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f4780e2bb52f3863a565ec3f699319d3493b83ff95ebbb4993e59c62aaf6e75e"},
{file = "ruff-0.1.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8f5b24daddf35b6c207619301170cae5d2699955829cda77b6ce1e5fc69340df"},
{file = "ruff-0.1.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d3f9ac658ba29e07b95c80fa742b059a55aefffa8b1e078bc3c08768bdd4b11a"},
{file = "ruff-0.1.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3521bf910104bf781e6753282282acc145cbe3eff79a1ce6b920404cd756075a"},
{file = "ruff-0.1.1-py3-none-win32.whl", hash = "sha256:ba3208543ab91d3e4032db2652dcb6c22a25787b85b8dc3aeff084afdc612e5c"},
{file = "ruff-0.1.1-py3-none-win_amd64.whl", hash = "sha256:3ff3006c97d9dc396b87fb46bb65818e614ad0181f059322df82bbfe6944e264"},
{file = "ruff-0.1.1-py3-none-win_arm64.whl", hash = "sha256:e140bd717c49164c8feb4f65c644046fe929c46f42493672853e3213d7bdbce2"},
{file = "ruff-0.1.1.tar.gz", hash = "sha256:c90461ae4abec261609e5ea436de4a4b5f2822921cf04c16d2cc9327182dbbcc"},
]
[[package]]
@ -3722,13 +3722,13 @@ wsproto = ">=0.14"
[[package]]
name = "twilio"
version = "8.9.1"
version = "8.10.0"
description = "Twilio API client and TwiML generator"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "twilio-8.9.1-py2.py3-none-any.whl", hash = "sha256:3edc0bcde7320b5ae5f516484af9092bc4df2f5a3b1d4d94a66c29310adb924c"},
{file = "twilio-8.9.1.tar.gz", hash = "sha256:7bca5dc476d4d15e89e41d3074f8a265bd61445d1de9e8a697ca96cd8399eda6"},
{file = "twilio-8.10.0-py2.py3-none-any.whl", hash = "sha256:1eb04af92f3e70fcc87a2fd30617f53784e34045d054e4ae3dc9cfe7bdf1e692"},
{file = "twilio-8.10.0.tar.gz", hash = "sha256:3bf2def228ceaa7519f4d6e58b2e3c9cb5d865af02b4618239e52c9d9e75e29d"},
]
[package.dependencies]

View File

@ -1,5 +1,5 @@
# Stage 1: Build website
FROM --platform=${BUILDPLATFORM} docker.io/node:20 as web-builder
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as web-builder
ENV NODE_ENV=production
WORKDIR /static

View File

@ -40934,10 +40934,20 @@ components:
type: string
readOnly: true
nullable: true
oidc_well_known_url:
type: string
readOnly: true
nullable: true
oidc_jwks_url:
type: string
readOnly: true
nullable: true
required:
- access_token_url
- authorization_url
- name
- oidc_jwks_url
- oidc_well_known_url
- profile_url
- request_token_url
- slug

View File

@ -9,10 +9,10 @@
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"@wdio/cli": "^8.19.0",
"@wdio/local-runner": "^8.19.0",
"@wdio/mocha-framework": "^8.19.0",
"@wdio/spec-reporter": "^8.19.0",
"@wdio/cli": "^8.20.1",
"@wdio/local-runner": "^8.20.0",
"@wdio/mocha-framework": "^8.20.0",
"@wdio/spec-reporter": "^8.20.0",
"eslint": "^8.51.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.21.0",
@ -1067,22 +1067,23 @@
}
},
"node_modules/@wdio/cli": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.19.0.tgz",
"integrity": "sha512-OLYIyVx1B6DK9xgiqFTNSZkDSug5so4MylwI7whJ1IdQmmwsRVS3rLuac0qYPr+z7G9QnZrqSrqCNkfwJ98V+Q==",
"version": "8.20.1",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.20.1.tgz",
"integrity": "sha512-R59wTu/IXUPnYKCDmunK97LmxzWVpYHpo/MnjqwWXvseRWAH6xKI7U3zGduON1M+c00U3wgl9SLKw2PF9h7hnw==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.1",
"@wdio/config": "8.19.0",
"@wdio/globals": "8.19.0",
"@wdio/config": "8.20.0",
"@wdio/globals": "8.20.0",
"@wdio/logger": "8.16.17",
"@wdio/protocols": "8.18.0",
"@wdio/types": "8.19.0",
"@wdio/utils": "8.19.0",
"@wdio/types": "8.20.0",
"@wdio/utils": "8.20.0",
"async-exit-hook": "^2.0.1",
"chalk": "^5.2.0",
"chokidar": "^3.5.3",
"cli-spinners": "^2.9.0",
"detect-package-manager": "^3.0.1",
"dotenv": "^16.3.1",
"ejs": "^3.1.9",
"execa": "^8.0.1",
@ -1093,9 +1094,8 @@
"lodash.union": "^4.6.0",
"read-pkg-up": "10.1.0",
"recursive-readdir": "^2.2.3",
"webdriverio": "8.19.0",
"yargs": "^17.7.2",
"yarn-install": "^1.0.0"
"webdriverio": "8.20.0",
"yargs": "^17.7.2"
},
"bin": {
"wdio": "bin/wdio.js"
@ -1117,14 +1117,14 @@
}
},
"node_modules/@wdio/config": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.19.0.tgz",
"integrity": "sha512-BFsLLoOD8kE1qGtAaY22N1c/GPOJbToQgD56ZZCS1wbLwX4EfZk6QIsqV2XcyEGzTZjge2GCkZEbUMHPLrMXvQ==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.20.0.tgz",
"integrity": "sha512-ODsafHlxEawyYa6IyIdXJMV2plPFyrDbGrXLNKNFBQVfB/FmoHUiiOTh+4Gu+sUXzpn2YNH5O199qHxHw61uUw==",
"dev": true,
"dependencies": {
"@wdio/logger": "8.16.17",
"@wdio/types": "8.19.0",
"@wdio/utils": "8.19.0",
"@wdio/types": "8.20.0",
"@wdio/utils": "8.20.0",
"decamelize": "^6.0.0",
"deepmerge-ts": "^5.0.0",
"glob": "^10.2.2",
@ -1136,29 +1136,29 @@
}
},
"node_modules/@wdio/globals": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.19.0.tgz",
"integrity": "sha512-upmDIy6HWB2mU8WC38OTnuo8984GVypzy2qUpGRcynXBuQLVLijxQLX+gGi4I5hBJu3K6eFhnDkhI0oXoV92gw==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.20.0.tgz",
"integrity": "sha512-IYqFM5Ofg1vWogIJOR+Tb5Q2jdyT2c3WJNDmVkHbRe1vP4pEWFf2BbAqzD3anMDssZD0y8I4ZDsFL+kMr5DENA==",
"dev": true,
"engines": {
"node": "^16.13 || >=18"
},
"optionalDependencies": {
"expect-webdriverio": "^4.2.5",
"webdriverio": "8.19.0"
"webdriverio": "8.20.0"
}
},
"node_modules/@wdio/local-runner": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.19.0.tgz",
"integrity": "sha512-WX9rN6WqqDipJhDQJV2+nDN4FY9sz3wmDdoi2X+W7KvnU8Hev2BexEb8PpzqVwt2aVL0gVwLb4cUdU7gWITHyg==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.20.0.tgz",
"integrity": "sha512-c/wSmCjzdLQ2BAq39BMhxTY2m+QDAB2quGSweou7s/V5OsAnu7Wb4z6+s2Y2ayeWypskVQXdhgmbUWAuktsSTQ==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.16.17",
"@wdio/repl": "8.10.1",
"@wdio/runner": "8.19.0",
"@wdio/types": "8.19.0",
"@wdio/runner": "8.20.0",
"@wdio/types": "8.20.0",
"async-exit-hook": "^2.0.1",
"split2": "^4.1.0",
"stream-buffers": "^3.0.2"
@ -1195,16 +1195,16 @@
}
},
"node_modules/@wdio/mocha-framework": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.19.0.tgz",
"integrity": "sha512-AtyTRnnRR/RM7yHQNa2oIwcGNYkd0boDxrtoSwl+qnUEN1lRjM3t+C7hYOTtv1J9PCGNtMK8pM4SD/IcujZHmA==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.20.0.tgz",
"integrity": "sha512-w5HUNO+XlpTP92r7A9Ule7CVofqdyKumyKph6pMeRGKFEINkHgJOxFqf98BgJQt2CfeMuMIy39LJMpBCViXLEA==",
"dev": true,
"dependencies": {
"@types/mocha": "^10.0.0",
"@types/node": "^20.1.0",
"@wdio/logger": "8.16.17",
"@wdio/types": "8.19.0",
"@wdio/utils": "8.19.0",
"@wdio/types": "8.20.0",
"@wdio/utils": "8.20.0",
"mocha": "^10.0.0"
},
"engines": {
@ -1230,14 +1230,14 @@
}
},
"node_modules/@wdio/reporter": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.19.0.tgz",
"integrity": "sha512-fRECsIIryM+2xnjcYDXx1j3c8GkPtBi5/dqowYPKW1bdm/SMCOBZviZVbihpw7zSgo+cGAMbFXEO9HDVcMqSjg==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.20.0.tgz",
"integrity": "sha512-9a0cIuwDYwMgBwx/JTRITjlxef63xEt+q+nQBsEwzaPtcTMLzRIGAYO7BKxf9ejYL3tdoPJYJm3GtBKeh+2QIQ==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.16.17",
"@wdio/types": "8.19.0",
"@wdio/types": "8.20.0",
"diff": "^5.0.0",
"object-inspect": "^1.12.0"
},
@ -1246,35 +1246,35 @@
}
},
"node_modules/@wdio/runner": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.19.0.tgz",
"integrity": "sha512-YZXVzg9Q4S/vRFfzzprQYgq9scPZohpSUhJxOjS4xYY/yorMRYTR/zih1aQCSQVgQ/9PadRqCs2a9fElsLdOMA==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.20.0.tgz",
"integrity": "sha512-8zvQanl3GM6PzY2kaj7cq+BFiA35cy9qXc25u3yKsY1/xjSuN5Mio0wijjwH4g9jQ6gobLdPflURfkJHB7pN9w==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/config": "8.19.0",
"@wdio/globals": "8.19.0",
"@wdio/config": "8.20.0",
"@wdio/globals": "8.20.0",
"@wdio/logger": "8.16.17",
"@wdio/types": "8.19.0",
"@wdio/utils": "8.19.0",
"@wdio/types": "8.20.0",
"@wdio/utils": "8.20.0",
"deepmerge-ts": "^5.0.0",
"expect-webdriverio": "^4.2.5",
"gaze": "^1.1.2",
"webdriver": "8.19.0",
"webdriverio": "8.19.0"
"webdriver": "8.20.0",
"webdriverio": "8.20.0"
},
"engines": {
"node": "^16.13 || >=18"
}
},
"node_modules/@wdio/spec-reporter": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.19.0.tgz",
"integrity": "sha512-3QV1AEJM/Utr8EitSpQI3JfNhGYryLVaQpIy4u/LxDj2NjHAebhs4eoEwsc1nUrtl0YXt5y6L5LopmxTpILDMw==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.20.0.tgz",
"integrity": "sha512-HpVE/99Kg/no94ETpI4JWoJzqpcsAnJQpbg5HdSyZqXuGj9WnRF/PGXK7VDU+DZwGQgOF9A6s6H0hd+FTHDrHg==",
"dev": true,
"dependencies": {
"@wdio/reporter": "8.19.0",
"@wdio/types": "8.19.0",
"@wdio/reporter": "8.20.0",
"@wdio/types": "8.20.0",
"chalk": "^5.1.2",
"easy-table": "^1.2.0",
"pretty-ms": "^7.0.0"
@ -1296,9 +1296,9 @@
}
},
"node_modules/@wdio/types": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.19.0.tgz",
"integrity": "sha512-L2DCjRkOYEkEcZewBMCCLrsFJIYzo+kUcoV8iX3oDH711pxdC6hJIK8r7EeeLDPklNHqnxGniVY/+04lpOoqmg==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.20.0.tgz",
"integrity": "sha512-y0En5V5PPF48IHJMetaNYQobhCr3ddsgp2aX/crLL51UccWqnFpCL8pCh6cP01gRgCchCasa2JCBMB+PucbYmA==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0"
@ -1308,14 +1308,14 @@
}
},
"node_modules/@wdio/utils": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.19.0.tgz",
"integrity": "sha512-Pwpoc0yqFMtVVv7Wp5zAJKO8qNRcbVHRGOdc62UFpXD09+kvnwhsgCJcQPPQndCebbDgvhFok3rBcgYrjEz5rQ==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.20.0.tgz",
"integrity": "sha512-nZ5QF5lPyZNJG9YaSrRuVfkVeg80yRrUQT42D0mUDDjmUIh2pAXDMu4HxgxocuQSOyLacg4Vpg3Sju9NFipxIA==",
"dev": true,
"dependencies": {
"@puppeteer/browsers": "^1.6.0",
"@wdio/logger": "8.16.17",
"@wdio/types": "8.19.0",
"@wdio/types": "8.20.0",
"decamelize": "^6.0.0",
"deepmerge-ts": "^5.1.0",
"edgedriver": "^5.3.5",
@ -1794,194 +1794,6 @@
"node": ">=0.2.0"
}
},
"node_modules/cac": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/cac/-/cac-3.0.4.tgz",
"integrity": "sha512-hq4rxE3NT5PlaEiVV39Z45d6MoFcQZG5dsgJqtAUeOz3408LEQAElToDkf9i5IYSCOmK0If/81dLg7nKxqPR0w==",
"dev": true,
"dependencies": {
"camelcase-keys": "^3.0.0",
"chalk": "^1.1.3",
"indent-string": "^3.0.0",
"minimist": "^1.2.0",
"read-pkg-up": "^1.0.1",
"suffix": "^0.1.0",
"text-table": "^0.2.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/cac/node_modules/ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
"dev": true,
"dependencies": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/find-up": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
"integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
"dev": true,
"dependencies": {
"path-exists": "^2.0.0",
"pinkie-promise": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.1.2",
"parse-json": "^2.2.0",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0",
"strip-bom": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
"dev": true,
"dependencies": {
"error-ex": "^1.2.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/path-exists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
"integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
"dev": true,
"dependencies": {
"pinkie-promise": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/path-type": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
"integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.1.2",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
"integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==",
"dev": true,
"dependencies": {
"load-json-file": "^1.0.0",
"normalize-package-data": "^2.3.2",
"path-type": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/read-pkg-up": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
"integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==",
"dev": true,
"dependencies": {
"find-up": "^1.0.0",
"read-pkg": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
"dev": true,
"dependencies": {
"ansi-regex": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/strip-bom": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
"integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
"dev": true,
"dependencies": {
"is-utf8": "^0.2.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cac/node_modules/supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/cacheable-lookup": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
@ -2055,28 +1867,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/camelcase-keys": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-3.0.0.tgz",
"integrity": "sha512-U4E6A6aFyYnNW+tDt5/yIUKQURKXe3WMFPfX4FxrQFcwZ/R08AUk1xWcUtlr7oq6CV07Ji+aa69V2g7BSpblnQ==",
"dev": true,
"dependencies": {
"camelcase": "^3.0.0",
"map-obj": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/camelcase-keys/node_modules/camelcase": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
"integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/chainsaw": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
@ -2594,6 +2384,125 @@
"node": ">=6"
}
},
"node_modules/detect-package-manager": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/detect-package-manager/-/detect-package-manager-3.0.1.tgz",
"integrity": "sha512-qoHDH6+lMcpJPAScE7+5CYj91W0mxZNXTwZPrCqi1KMk+x+AoQScQ2V1QyqTln1rHU5Haq5fikvOGHv+leKD8A==",
"dev": true,
"dependencies": {
"execa": "^5.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/detect-package-manager/node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
"human-signals": "^2.1.0",
"is-stream": "^2.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.1",
"onetime": "^5.1.2",
"signal-exit": "^3.0.3",
"strip-final-newline": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/detect-package-manager/node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/detect-package-manager/node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
"engines": {
"node": ">=10.17.0"
}
},
"node_modules/detect-package-manager/node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/detect-package-manager/node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/detect-package-manager/node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
"dependencies": {
"path-key": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/detect-package-manager/node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/detect-package-manager/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"node_modules/detect-package-manager/node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/devtools-protocol": {
"version": "0.0.1209236",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1209236.tgz",
@ -4090,27 +3999,6 @@
"node": ">= 0.4.0"
}
},
"node_modules/has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
"dev": true,
"dependencies": {
"ansi-regex": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/has-ansi/node_modules/ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
@ -4325,15 +4213,6 @@
"node": ">=0.8.19"
}
},
"node_modules/indent-string": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
"integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -4712,12 +4591,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-utf8": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
"integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
"dev": true
},
"node_modules/is-weakref": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
@ -5622,15 +5495,6 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"node_modules/map-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/memorystream": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
@ -6648,27 +6512,6 @@
"node": ">=4"
}
},
"node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
"dev": true,
"dependencies": {
"pinkie": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -6783,12 +6626,6 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
"dev": true
},
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@ -8066,15 +7903,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/suffix": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/suffix/-/suffix-0.1.1.tgz",
"integrity": "sha512-j5uf6MJtMCfC4vBe5LFktSe4bGyNTBk7I2Kdri0jeLrcv5B9pWfxVa5JQpoxgtR8vaVB7bVxsWgnfQbX5wkhAA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -8693,18 +8521,18 @@
}
},
"node_modules/webdriver": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.19.0.tgz",
"integrity": "sha512-7LLDiiAnhUE4AsQjbpql7bPxVYGg7fOgrncebRSnwerPeFDnjMxV+MNs42bIpQFscncYAndKZR5t1DP1vC240A==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.20.0.tgz",
"integrity": "sha512-U/sej7yljVf/enEWR9L2AtOntrd3lqtkEtHeuSWU2FPp5cWvoMEe7vQiG0WJA74VE2e7uwd8S1LfCgQD1wY3Bg==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@types/ws": "^8.5.3",
"@wdio/config": "8.19.0",
"@wdio/config": "8.20.0",
"@wdio/logger": "8.16.17",
"@wdio/protocols": "8.18.0",
"@wdio/types": "8.19.0",
"@wdio/utils": "8.19.0",
"@wdio/types": "8.20.0",
"@wdio/utils": "8.20.0",
"deepmerge-ts": "^5.1.0",
"got": "^ 12.6.1",
"ky": "^0.33.0",
@ -8752,18 +8580,18 @@
}
},
"node_modules/webdriverio": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.19.0.tgz",
"integrity": "sha512-U+TDtkJBEkqD7Rux1EKsYTxmlwNt/l9WnDaO1oVQyazk5WRBGdtMxtF7Cm1AspSR0swsnx2NFBSte0IgI8mzUg==",
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.20.0.tgz",
"integrity": "sha512-nVd3n4v1CYzjEezK6OgmGIcVx+T/7PNYwLK3fTNH2hGRNX05TyGGcR9HAcVZCbIu8WWFKRE0SrLvCjEutPO8gg==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/config": "8.19.0",
"@wdio/config": "8.20.0",
"@wdio/logger": "8.16.17",
"@wdio/protocols": "8.18.0",
"@wdio/repl": "8.10.1",
"@wdio/types": "8.19.0",
"@wdio/utils": "8.19.0",
"@wdio/types": "8.20.0",
"@wdio/utils": "8.20.0",
"archiver": "^6.0.0",
"aria-query": "^5.0.0",
"css-shorthand-properties": "^1.1.1",
@ -8780,7 +8608,7 @@
"resq": "^1.9.1",
"rgb2hex": "0.2.5",
"serialize-error": "^11.0.1",
"webdriver": "8.19.0"
"webdriver": "8.20.0"
},
"engines": {
"node": "^16.13 || >=18"
@ -9126,123 +8954,6 @@
"node": ">=12"
}
},
"node_modules/yarn-install": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/yarn-install/-/yarn-install-1.0.0.tgz",
"integrity": "sha512-VO1u181msinhPcGvQTVMnHVOae8zjX/NSksR17e6eXHRveDvHCF5mGjh9hkN8mzyfnCqcBe42LdTs7bScuTaeg==",
"dev": true,
"dependencies": {
"cac": "^3.0.3",
"chalk": "^1.1.3",
"cross-spawn": "^4.0.2"
},
"bin": {
"yarn-install": "bin/yarn-install.js",
"yarn-remove": "bin/yarn-remove.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/yarn-install/node_modules/ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/yarn-install/node_modules/ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/yarn-install/node_modules/chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
"dev": true,
"dependencies": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/yarn-install/node_modules/cross-spawn": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
"integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==",
"dev": true,
"dependencies": {
"lru-cache": "^4.0.1",
"which": "^1.2.9"
}
},
"node_modules/yarn-install/node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
"node_modules/yarn-install/node_modules/lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"dev": true,
"dependencies": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"node_modules/yarn-install/node_modules/strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
"dev": true,
"dependencies": {
"ansi-regex": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/yarn-install/node_modules/supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/yarn-install/node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"which": "bin/which"
}
},
"node_modules/yarn-install/node_modules/yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
"dev": true
},
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",

View File

@ -6,10 +6,10 @@
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"@wdio/cli": "^8.19.0",
"@wdio/local-runner": "^8.19.0",
"@wdio/mocha-framework": "^8.19.0",
"@wdio/spec-reporter": "^8.19.0",
"@wdio/cli": "^8.20.1",
"@wdio/local-runner": "^8.20.0",
"@wdio/mocha-framework": "^8.20.0",
"@wdio/spec-reporter": "^8.20.0",
"eslint": "^8.51.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.21.0",

1842
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@
"@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.0",
"@fortawesome/fontawesome-free": "^6.4.2",
"@goauthentik/api": "^2023.8.3-1697651039",
"@goauthentik/api": "^2023.8.3-1697813667",
"@lit-labs/context": "^0.4.1",
"@lit-labs/task": "^3.1.0",
"@lit/localize": "^0.11.4",
@ -53,7 +53,7 @@
"chartjs-adapter-moment": "^1.0.1",
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.33.0",
"core-js": "^3.33.1",
"country-flag-icons": "^1.5.7",
"fuse.js": "^6.6.2",
"lit": "^2.8.0",
@ -82,11 +82,11 @@
"@rollup/plugin-replace": "^5.0.4",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.5",
"@storybook/addon-essentials": "^7.5.0",
"@storybook/addon-links": "^7.5.0",
"@storybook/addon-essentials": "^7.5.1",
"@storybook/addon-links": "^7.5.1",
"@storybook/blocks": "^7.1.1",
"@storybook/web-components": "^7.5.0",
"@storybook/web-components-vite": "^7.5.0",
"@storybook/web-components": "^7.5.1",
"@storybook/web-components-vite": "^7.5.1",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/chart.js": "^2.9.39",
"@types/codemirror": "5.60.12",
@ -113,7 +113,7 @@
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-cssimport": "^1.0.3",
"rollup-plugin-postcss-lit": "^2.1.0",
"storybook": "^7.5.0",
"storybook": "^7.5.1",
"storybook-addon-mock": "^4.3.0",
"ts-lit-plugin": "^1.2.1",
"tslib": "^2.6.2",

View File

@ -192,7 +192,11 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
>
<input
type="text"
value="${ifDefined(this.instance?.oidcWellKnownUrl)}"
value="${first(
this.instance?.oidcWellKnownUrl,
this.providerType.oidcWellKnownUrl,
"",
)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
@ -207,7 +211,11 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
>
<input
type="text"
value="${ifDefined(this.instance?.oidcJwksUrl)}"
value="${first(
this.instance?.oidcJwksUrl,
this.providerType.oidcJwksUrl,
"",
)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">

View File

@ -22,7 +22,7 @@ import { type WizardButton, WizardStepLabel } from "./types";
*
* @element ak-wizard-frame
*
* @slot - Where the form itself should go
* @slot trigger - (Inherited from ModalButton) Define the "summon modal" button here
*
* @fires ak-wizard-nav - Tell the orchestrator what page the user wishes to move to.
*

View File

@ -1,12 +1,14 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { MessageLevel } from "@goauthentik/common/messages";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { isSafari } from "@goauthentik/elements/utils/isSafari";
import { writeToClipboard } from "@goauthentik/elements/utils/writeToClipboard";
import { msg } from "@lit/localize";
import { customElement, property } from "lit/decorators.js";
import { CoreApi, ResponseError, TokenView } from "@goauthentik/api";
import { APIMessage } from "../../messages/Message";
import BaseTaskButton from "../SpinnerButton/BaseTaskButton";
/**
@ -51,35 +53,26 @@ export class TokenCopyButton extends BaseTaskButton {
});
};
onSuccess(token: unknown) {
async onSuccess(token: unknown) {
super.onSuccess(token);
if (!isTokenView(token)) {
throw new Error(`Unrecognized return from server: ${token}`);
}
// Insecure origins may not have access to the clipboard. Show a message instead.
if (!navigator.clipboard) {
const wroteToClipboard = await writeToClipboard(token.key as string);
const info: Pick<APIMessage, "message" | "description"> = wroteToClipboard
? {
message: msg("The token has been copied to your clipboard"),
}
: {
message: token.key,
description: msg(
"The token was displayed because authentik does not have permission to write to the clipboard",
),
};
showMessage({
level: MessageLevel.info,
message: token.key as string,
...info,
});
return;
}
// Safari only allows navigator.clipboard.write with native clipboard items.
if (isSafari()) {
navigator.clipboard.write([
new ClipboardItem({
"text/plain": new Blob([token.key as string], {
type: "text/plain",
}),
}),
]);
return;
}
// Default behavior: write the token to the clipboard.
navigator.clipboard.writeText(token.key as string);
}
async onError(error: unknown) {

View File

@ -0,0 +1,26 @@
import { isSafari } from "./isSafari";
export async function writeToClipboard(message: string) {
if (!navigator.clipboard) {
return false;
}
// Safari only allows navigator.clipboard.write with native clipboard items.
try {
if (isSafari()) {
await navigator.clipboard.write([
new ClipboardItem({
"text/plain": new Blob([message], {
type: "text/plain",
}),
}),
]);
} else {
await navigator.clipboard.writeText(message);
}
return true;
} catch (_) {
/* no op */
}
return false;
}

View File

@ -7868,27 +7868,35 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s4bd386db7302bb22">
<source>Create With Wizard</source>
<target>通过向导创建</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>“新应用程序向导”提示目前已隐藏</target>
</trans-unit>
<trans-unit id="s61bd841e66966325">
<source>External applications that use authentik as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.</source>
<target>通过 OAuth2 和 SAML 等协议,使用 authentik 作为身份提供程序的外部应用程序。此处显示了所有应用程序,即使您无法访问的也包括在内。</target>
</trans-unit>
<trans-unit id="s1cc306d8e28c4464">
<source>Deny message</source>
<target>拒绝消息</target>
</trans-unit>
<trans-unit id="s6985c401e1100122">
<source>Message shown when this stage is run.</source>
<target>此阶段运行时显示的消息。</target>
</trans-unit>
<trans-unit id="s09f0c100d0ad2fec">
<source>Open Wizard</source>
<target>打开向导</target>
</trans-unit>
<trans-unit id="sf2ef885f7d0a101d">
<source>Demo Wizard</source>
<target>演示向导</target>
</trans-unit>
<trans-unit id="s77505ee5d2e45e53">
<source>Run the demo wizard</source>
<target>运行演示向导</target>
</trans-unit>
</body>
</file>

View File

@ -2262,11 +2262,6 @@
<source>Applications</source>
<target>应用程序</target>
</trans-unit>
<trans-unit id="sb9024c1640c4da12">
<source>External Applications which use authentik as Identity-Provider, utilizing protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.</source>
<target>利用 OAuth2 和 SAML 等协议,使用 authentik 作为身份提供程序的外部应用程序。此处显示了所有应用程序,即使您无法访问的也包括在内。</target>
</trans-unit>
<trans-unit id="s96b2fefc550e4b1c">
<source>Provider Type</source>
@ -7870,6 +7865,38 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s2da4aa7a9abeb653">
<source>Pseudolocale (for testing)</source>
<target>伪区域(测试用)</target>
</trans-unit>
<trans-unit id="s4bd386db7302bb22">
<source>Create With Wizard</source>
<target>通过向导创建</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>“新应用程序向导”提示目前已隐藏</target>
</trans-unit>
<trans-unit id="s61bd841e66966325">
<source>External applications that use authentik as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.</source>
<target>通过 OAuth2 和 SAML 等协议,使用 authentik 作为身份提供程序的外部应用程序。此处显示了所有应用程序,即使您无法访问的也包括在内。</target>
</trans-unit>
<trans-unit id="s1cc306d8e28c4464">
<source>Deny message</source>
<target>拒绝消息</target>
</trans-unit>
<trans-unit id="s6985c401e1100122">
<source>Message shown when this stage is run.</source>
<target>此阶段运行时显示的消息。</target>
</trans-unit>
<trans-unit id="s09f0c100d0ad2fec">
<source>Open Wizard</source>
<target>打开向导</target>
</trans-unit>
<trans-unit id="sf2ef885f7d0a101d">
<source>Demo Wizard</source>
<target>演示向导</target>
</trans-unit>
<trans-unit id="s77505ee5d2e45e53">
<source>Run the demo wizard</source>
<target>运行演示向导</target>
</trans-unit>
</body>
</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -101,23 +101,23 @@ Many of these vendors also received some benefit of the doubt. SSO generally tak
A few companies have tried to make some attention by removing the SSO tax including Tuple and [Scalr](https://www.scalr.com/blog/sso-tax) but none have really gone viral for the effort.
**3. The “tragedy of the commons” effect**
**3. The collective action problem traps individuals**
The “tragedy of the commons” is an idea that came out of ecological research in the late 1960s. The “commons” refers to a shared resource, such as a water source, and the “tragedy” is that individuals will each use more of the resource than it can withstand.
The previous two reasons the SSO tax movement failed focused on problems at the individual company level, but the greatest reason might be industry-wide.
Each individual wants to get as much as possible from the commons, but when everyone takes as much water as they want, in this example, the entire resource dies off, and everyone is worse off.
If we zoom out, the SSO tax isnt just a business decision its a collective action problem.
![!["Cartoon of the tragedy of the commons by <a href="https://sketchplanations.com/the-tragedy-of-the-commons">Sketchplanatons</a>"]](./image2.png)
A collective action problem is when individuals in a given situation would benefit from cooperating but, because of other incentives, work against each other to the detriment of all. People keep driving cars, for example, due to a wide variety of valid individual incentives but traffic, pollution, and climate change eventually hurt the collective including the drivers.
The idea has since spread to politics, economics, and business. If theres a situation where individual incentives can defeat collective incentives and shared resources can be destroyed by individuals thinking for themselves, a tragedy of the commons effect is likely.
As the software supply chain has evolved, open-source adoption has grown, and software companies have become increasingly interconnected, software security has begun to resemble a commons.
As the software supply chain has evolved, open-source adoption has grown, and software companies have become increasingly interconnected, software security has become an issue that affects the entire industry. The SSO tax shows, however, that a collective action problem hinders taking the steps necessary to improve security for everyone.
In the past, companies considered security in an organization vs. attacker model, as one entity building a perimeter to defend itself against targeted attackers. But in modern security, organizations are so interconnected that attackers can leap from organization to organization and move laterally from low-value vulnerabilities to high-value exploits.
When attackers [hacked Target in 2013](https://slate.com/technology/2022/04/breached-excerpt-hartzog-solove-target.html#:~:text=In%20caper%20movies%2C%20the%20criminals,party%20vendor%20hired%20by%20Target.), they didnt go after Target directly; they entered via a third-party vendor Target had hired. And when Log4j became [headline news in 2022](https://builtin.com/cybersecurity/log4j-vulerability-explained), it wasnt because one attacker found one exploit; a vast range of companies suddenly realized they were vulnerable because they had all adopted the same open-source component.
The more interconnected organizations are, the more security becomes a commons, and the more the SSO tax becomes a tragedy. Ed Contreras, Chief Information Security Officer at Frost Bank, said it well in an [interview with CISO Series](https://cisoseries.com/we-shame-others-because-were-so-right-about-everything/): “With single sign-on, were protecting both of our companies” and that the SSO tax, as a result, is an “atrocity.”
The more interconnected organizations are, the more security becomes a collective action problem that demands companies shift from prioritizing profits via security taxes to pursuing industry-wide security by offering accessible security features and reinforcing security best practices.
Ed Contreras, Chief Information Security Officer at Frost Bank, said it well in an [interview with CISO Series](https://cisoseries.com/we-shame-others-because-were-so-right-about-everything): “With single sign-on, were protecting both of our companies” and that the SSO tax, as a result, is an “atrocity.”
## Compromise is the only way out