Merge branch 'dev' into web/config-provider
* dev: web: bump API Client version (#7803) events: add graph for event volume (#7639) website/docs: change links to point to our YouTube (#7794) web: bump core-js from 3.33.3 to 3.34.0 in /web (#7796) core: bump golang from 1.21.4-bookworm to 1.21.5-bookworm (#7798) web: bump the wdio group in /tests/wdio with 4 updates (#7799) web/admin: revise wizard form handling (#7331) web: bump the eslint group in /tests/wdio with 2 updates (#7783) web: bump the sentry group in /web with 2 updates (#7784) web: bump the eslint group in /web with 2 updates (#7785) web: bump chart.js from 4.4.0 to 4.4.1 in /web (#7786) website: bump @types/react from 18.2.41 to 18.2.42 in /website (#7787) website: bump react-tooltip from 5.24.0 to 5.25.0 in /website (#7788) outposts/ldap: avoid nil ptr deref in MemorySearcher (#7767)
This commit is contained in:
commit
849fea6e91
|
@ -35,7 +35,7 @@ COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
|
|||
RUN npm run build
|
||||
|
||||
# Stage 3: Build go proxy
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.4-bookworm AS go-builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS go-builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
|
|
@ -5,7 +5,7 @@ from json import loads
|
|||
import django_filters
|
||||
from django.db.models.aggregates import Count
|
||||
from django.db.models.fields.json import KeyTextTransform, KeyTransform
|
||||
from django.db.models.functions import ExtractDay
|
||||
from django.db.models.functions import ExtractDay, ExtractHour
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
||||
from guardian.shortcuts import get_objects_for_user
|
||||
|
@ -149,7 +149,15 @@ class EventViewSet(ModelViewSet):
|
|||
return Response(EventTopPerUserSerializer(instance=events, many=True).data)
|
||||
|
||||
@extend_schema(
|
||||
methods=["GET"],
|
||||
responses={200: CoordinateSerializer(many=True)},
|
||||
)
|
||||
@action(detail=False, methods=["GET"], pagination_class=None)
|
||||
def volume(self, request: Request) -> Response:
|
||||
"""Get event volume for specified filters and timeframe"""
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
return Response(queryset.get_events_per(timedelta(days=7), ExtractHour, 7 * 3))
|
||||
|
||||
@extend_schema(
|
||||
responses={200: CoordinateSerializer(many=True)},
|
||||
filters=[],
|
||||
parameters=[
|
||||
|
|
|
@ -147,7 +147,11 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult,
|
|||
fg := api.NewGroup(g.Pk, g.NumPk, g.Name, g.ParentName, []api.GroupMember{u}, []api.Role{})
|
||||
fg.SetUsers([]int32{flag.UserPk})
|
||||
if g.Parent.IsSet() {
|
||||
fg.SetParent(*g.Parent.Get())
|
||||
if p := g.Parent.Get(); p != nil {
|
||||
fg.SetParent(*p)
|
||||
} else {
|
||||
fg.SetParentNil()
|
||||
}
|
||||
}
|
||||
fg.SetAttributes(g.Attributes)
|
||||
fg.SetIsSuperuser(*g.IsSuperuser)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.4-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,7 @@ COPY web .
|
|||
RUN npm run build-proxy
|
||||
|
||||
# Stage 2: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.4-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.4-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
|
80
schema.yml
80
schema.yml
|
@ -6276,6 +6276,86 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/events/events/volume/:
|
||||
get:
|
||||
operationId: events_events_volume_list
|
||||
description: Get event volume for specified filters and timeframe
|
||||
parameters:
|
||||
- in: query
|
||||
name: action
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: client_ip
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: context_authorized_app
|
||||
schema:
|
||||
type: string
|
||||
description: Context Authorized application
|
||||
- in: query
|
||||
name: context_model_app
|
||||
schema:
|
||||
type: string
|
||||
description: Context Model App
|
||||
- in: query
|
||||
name: context_model_name
|
||||
schema:
|
||||
type: string
|
||||
description: Context Model Name
|
||||
- in: query
|
||||
name: context_model_pk
|
||||
schema:
|
||||
type: string
|
||||
description: Context Model Primary Key
|
||||
- name: ordering
|
||||
required: false
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
schema:
|
||||
type: string
|
||||
- name: search
|
||||
required: false
|
||||
in: query
|
||||
description: A search term.
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: tenant_name
|
||||
schema:
|
||||
type: string
|
||||
description: Tenant name
|
||||
- in: query
|
||||
name: username
|
||||
schema:
|
||||
type: string
|
||||
description: Username
|
||||
tags:
|
||||
- events
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Coordinate'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/events/notifications/:
|
||||
get:
|
||||
operationId: events_notifications_list
|
||||
|
|
454
tests/wdio/package-lock.json
generated
454
tests/wdio/package-lock.json
generated
|
@ -7,12 +7,12 @@
|
|||
"name": "@goauthentik/web-tests",
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||
"@typescript-eslint/parser": "^6.13.1",
|
||||
"@wdio/cli": "^8.24.6",
|
||||
"@wdio/local-runner": "^8.24.6",
|
||||
"@wdio/mocha-framework": "^8.24.6",
|
||||
"@wdio/spec-reporter": "^8.24.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"@wdio/cli": "^8.24.13",
|
||||
"@wdio/local-runner": "^8.24.12",
|
||||
"@wdio/mocha-framework": "^8.24.12",
|
||||
"@wdio/spec-reporter": "^8.24.12",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-plugin-sonarjs": "^0.23.0",
|
||||
|
@ -946,16 +946,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.1.tgz",
|
||||
"integrity": "sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz",
|
||||
"integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.1",
|
||||
"@typescript-eslint/type-utils": "6.13.1",
|
||||
"@typescript-eslint/utils": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.2",
|
||||
"@typescript-eslint/type-utils": "6.13.2",
|
||||
"@typescript-eslint/utils": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2",
|
||||
"debug": "^4.3.4",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
|
@ -981,15 +981,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.1.tgz",
|
||||
"integrity": "sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz",
|
||||
"integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "6.13.1",
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/typescript-estree": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.2",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/typescript-estree": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1009,13 +1009,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz",
|
||||
"integrity": "sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz",
|
||||
"integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1"
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
|
@ -1026,13 +1026,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz",
|
||||
"integrity": "sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz",
|
||||
"integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "6.13.1",
|
||||
"@typescript-eslint/utils": "6.13.1",
|
||||
"@typescript-eslint/typescript-estree": "6.13.2",
|
||||
"@typescript-eslint/utils": "6.13.2",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
|
@ -1053,9 +1053,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.1.tgz",
|
||||
"integrity": "sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz",
|
||||
"integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
|
@ -1066,13 +1066,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz",
|
||||
"integrity": "sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz",
|
||||
"integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
|
@ -1093,17 +1093,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.1.tgz",
|
||||
"integrity": "sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz",
|
||||
"integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==",
|
||||
"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.13.1",
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/typescript-estree": "6.13.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.2",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/typescript-estree": "6.13.2",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1118,12 +1118,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz",
|
||||
"integrity": "sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz",
|
||||
"integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1141,34 +1141,33 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@wdio/cli": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.24.6.tgz",
|
||||
"integrity": "sha512-QXRiP1FeGaSmUO24pFhyzP6lZY/FsZAhXyofl3r6TGwTlnw9i4S7C4Te2qQcccgAQq03rdSK058YURPwbiKhmg==",
|
||||
"version": "8.24.13",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.24.13.tgz",
|
||||
"integrity": "sha512-UG4dvnT6KfnKDsNVn/GeUidi21Pso6N6eu1O5oin9+fP612zpPFrx3/TuYrAfjJb+qmy1QkKq3zX99y+xlp7og==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.1",
|
||||
"@wdio/config": "8.24.6",
|
||||
"@wdio/globals": "8.24.6",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/protocols": "8.23.0",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/utils": "8.24.6",
|
||||
"@wdio/config": "8.24.12",
|
||||
"@wdio/globals": "8.24.12",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/protocols": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"@wdio/utils": "8.24.12",
|
||||
"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",
|
||||
"import-meta-resolve": "^3.0.0",
|
||||
"import-meta-resolve": "^4.0.0",
|
||||
"inquirer": "9.2.12",
|
||||
"lodash.flattendeep": "^4.4.0",
|
||||
"lodash.pickby": "^4.6.0",
|
||||
"lodash.union": "^4.6.0",
|
||||
"read-pkg-up": "^10.0.0",
|
||||
"recursive-readdir": "^2.2.3",
|
||||
"webdriverio": "8.24.6",
|
||||
"webdriverio": "8.24.12",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -1191,47 +1190,47 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/config": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.24.6.tgz",
|
||||
"integrity": "sha512-ZFmd6rB1kgL4k/SjLXbtFTCxvxSf1qzdt/losiTqkqFBYznkTRUBGSoGaVTlkMtHAReiVSK92sICc15JWaCdEA==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.24.12.tgz",
|
||||
"integrity": "sha512-3HW7qG1rIHzOIybV6oHR1CqLghsN0G3Xzs90ZciGL8dYhtcLtYCHwuWmBw4mkaB5xViU4AmZDuj7ChiG8Cr6Qw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/utils": "8.24.6",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"@wdio/utils": "8.24.12",
|
||||
"decamelize": "^6.0.0",
|
||||
"deepmerge-ts": "^5.0.0",
|
||||
"glob": "^10.2.2",
|
||||
"import-meta-resolve": "^3.0.0"
|
||||
"import-meta-resolve": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.13 || >=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@wdio/globals": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.24.6.tgz",
|
||||
"integrity": "sha512-v5Sjyix9ddrxPM8DCf0vADUxr21Fx7nWVYS6Z/gkTEhuQbi5svjs6EGjMmErO6tp3CY4SNTUiz+ZFJw9YH4Swg==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.24.12.tgz",
|
||||
"integrity": "sha512-uF26a89Q+6DdqzSfK9suXJNdWYJnsazjzPuq4Xtz6nKdjgmBufSeX1JHV4LxErEu5b/IdzVcMCUKKEvsZPc9vA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^16.13 || >=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"expect-webdriverio": "^4.6.1",
|
||||
"webdriverio": "8.24.6"
|
||||
"webdriverio": "8.24.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@wdio/local-runner": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.24.6.tgz",
|
||||
"integrity": "sha512-fd91CxlVpOpSxg+QuqgdFl66kEtY7R/ohdKBXNhdMXtXFb4EQIGp/igiMBvuTHcHUMHOw3N8KaHfe6YXo+6Qyw==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.24.12.tgz",
|
||||
"integrity": "sha512-Q1lfdSPDEgKwuE1gNucJrkVfgOJLTjtnYGb7Fe7oYUHGDwjkudjSBJYmyx30qFZKfZ4zRqXtaEdys54/0TxibA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/repl": "8.23.1",
|
||||
"@wdio/runner": "8.24.6",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/repl": "8.24.12",
|
||||
"@wdio/runner": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"async-exit-hook": "^2.0.1",
|
||||
"split2": "^4.1.0",
|
||||
"stream-buffers": "^3.0.2"
|
||||
|
@ -1241,9 +1240,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/logger": {
|
||||
"version": "8.16.17",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.16.17.tgz",
|
||||
"integrity": "sha512-zeQ41z3T+b4IsrriZZipayXxLNDuGsm7TdExaviNGojPVrIsQUCSd/FvlLHM32b7ZrMyInHenu/zx1cjAZO71g==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.24.12.tgz",
|
||||
"integrity": "sha512-QisOiVIWKTUCf1H7S+DOtC+gruhlpimQrUXfWMTeeh672PvAJYnTpOJDWA+BtXfsikkUYFAzAaq8SeMJk8rqKg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^5.1.2",
|
||||
|
@ -1268,16 +1267,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/mocha-framework": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.24.6.tgz",
|
||||
"integrity": "sha512-qTRU7trzPJKjdlO6r4+YnyauEQ/cTvCJYRl5t2jqsG8y2OoCRsw4qUydzGTxX3YEkmgZjSN845hMNtyWuZUjcg==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.24.12.tgz",
|
||||
"integrity": "sha512-SHN7CYZnDkVUNYxLp8iMV92xcmU/4gq5dqA0pRrK4m5nIU7BoL0flm0kA+ydYUQyNedQh2ru1V63uNyTOyCKAg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/node": "^20.1.0",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/utils": "8.24.6",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"@wdio/utils": "8.24.12",
|
||||
"mocha": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1285,15 +1284,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/protocols": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.23.0.tgz",
|
||||
"integrity": "sha512-2XTzD+lqQP3g8BWn+Bn5BTFzjHqzZNwq7DjlYrb27Bq8nOA+1DEcj3WzQ6V6CktTnKI/LAYKA1IFAF//Azrp/Q==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.24.12.tgz",
|
||||
"integrity": "sha512-QnVj3FkapmVD3h2zoZk+ZQ8gevSj9D9MiIQIy8eOnY4FAneYZ9R9GvoW+mgNcCZO8S8++S/jZHetR8n+8Q808g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@wdio/repl": {
|
||||
"version": "8.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-8.23.1.tgz",
|
||||
"integrity": "sha512-u6zG2cgBm67V5/WlQzadWqLGXs3moH8MOsgoljULQncelSBBZGZ5DyLB4p7jKcUAsKtMjgmFQmIvpQoqmyvdfg==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-8.24.12.tgz",
|
||||
"integrity": "sha512-321F3sWafnlw93uRTSjEBVuvWCxTkWNDs7ektQS15drrroL3TMeFOynu4rDrIz0jXD9Vas0HCD2Tq/P0uxFLdw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0"
|
||||
|
@ -1303,14 +1302,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/reporter": {
|
||||
"version": "8.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.24.2.tgz",
|
||||
"integrity": "sha512-10hTEk4JIIXW8hnwyxTNgby1ZxoJAbXH9d/eMbkEoAwxx/eqaM+ghPs1GSrzOIjjZ3lwz369POEYfJcLkw3g2w==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.24.12.tgz",
|
||||
"integrity": "sha512-FtLzDTBXdgxXf4T9HJQ2bNpYYSKEw//jojFm9XzB4fPwzPeFY3HC+dbePucVW1SSLrVzVxqIOyHiwCLqQ/4cQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"diff": "^5.0.0",
|
||||
"object-inspect": "^1.12.0"
|
||||
},
|
||||
|
@ -1319,35 +1318,35 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/runner": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.24.6.tgz",
|
||||
"integrity": "sha512-2dt5F9scy0klYwB/E4JztLo04OaPsqcuZP9WKn+NSIBNug0UrgUcBv5ARJEuE3iUyPWpTeczWkU3UtcdMmjagQ==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.24.12.tgz",
|
||||
"integrity": "sha512-wiwXZWG12YDe7GCYBnZ1xEg3UKi18Rvh4RNQiumjypDOErJit1hOCppbJ37LqLqQu+tfWGfN73j46yR7fQOCHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0",
|
||||
"@wdio/config": "8.24.6",
|
||||
"@wdio/globals": "8.24.6",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/utils": "8.24.6",
|
||||
"@wdio/config": "8.24.12",
|
||||
"@wdio/globals": "8.24.12",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"@wdio/utils": "8.24.12",
|
||||
"deepmerge-ts": "^5.0.0",
|
||||
"expect-webdriverio": "^4.6.1",
|
||||
"gaze": "^1.1.2",
|
||||
"webdriver": "8.24.6",
|
||||
"webdriverio": "8.24.6"
|
||||
"webdriver": "8.24.12",
|
||||
"webdriverio": "8.24.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.13 || >=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@wdio/spec-reporter": {
|
||||
"version": "8.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.24.2.tgz",
|
||||
"integrity": "sha512-FJ1+/kgxlw4ong+5PJJcOzLf8B/TzPL9hGeOF2xoWkk2uMsmNBJN2r27pjtfFxA41lw4q+Oav0Vb/RhdCB601Q==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.24.12.tgz",
|
||||
"integrity": "sha512-Ng3ErWK8eESamCYwIr2Uv49+46RvmT8FnmGaJ6irJoAp101K8zENEs1pyqYHJReucN+ka/wM87blfc2k8NEHCA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@wdio/reporter": "8.24.2",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/reporter": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"chalk": "^5.1.2",
|
||||
"easy-table": "^1.2.0",
|
||||
"pretty-ms": "^7.0.0"
|
||||
|
@ -1369,9 +1368,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/types": {
|
||||
"version": "8.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.24.2.tgz",
|
||||
"integrity": "sha512-x7iWF5NM8NfVxziGwLdQ+3sstgSxRoqfmmFEDTDps0oFrN5CgkqcoLkqXJ5u166gvpxpEq0gxZwxkbPC/Lp0cw==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.24.12.tgz",
|
||||
"integrity": "sha512-SaD3OacDiW06DvSgAQ7sDBbpiI9qZRg7eoVYeBg3uSGVtUq84vTETRhhV7D6xTC00IqZu+mmN2TY5/q+7Gqy7w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0"
|
||||
|
@ -1381,21 +1380,20 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wdio/utils": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.24.6.tgz",
|
||||
"integrity": "sha512-qwcshLH9iKnhK0jXoXjPw3G02UhyShT0I+ljC0hMybJEBsra92TYFa47Cp6n1fdvM3+/BTuhsgtzRz0anObicQ==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.24.12.tgz",
|
||||
"integrity": "sha512-uzwZyBVgqz0Wz1KL3aOUaQsxT8TNkzxti4NNTSMrU256qAPqc/n75rB7V73QASapCMpy70mZZTsuPgQYYj4ytQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@puppeteer/browsers": "^1.6.0",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"decamelize": "^6.0.0",
|
||||
"deepmerge-ts": "^5.1.0",
|
||||
"edgedriver": "^5.3.5",
|
||||
"geckodriver": "^4.2.0",
|
||||
"get-port": "^7.0.0",
|
||||
"got": "^13.0.0",
|
||||
"import-meta-resolve": "^3.0.0",
|
||||
"import-meta-resolve": "^4.0.0",
|
||||
"locate-app": "^2.1.0",
|
||||
"safaridriver": "^0.1.0",
|
||||
"split2": "^4.2.0",
|
||||
|
@ -2457,129 +2455,10 @@
|
|||
"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.1213968",
|
||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1213968.tgz",
|
||||
"integrity": "sha512-o4n/beY+3CcZwFctYapjGelKptR4AuQT5gXS1Kvgbig+ArwkxK7f8wDVuD1wsoswiJWCwV6OK+Qb7vhNzNmABQ==",
|
||||
"version": "0.0.1233178",
|
||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1233178.tgz",
|
||||
"integrity": "sha512-jmMfyaqlzddwmDaSR1AQ+5ek+f7rupZdxKuPdkRcoxrZoF70Idg/4dTgXA08TLPmwAwB54gh49Wm2l/gRM0eUg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/diff": {
|
||||
|
@ -4008,43 +3887,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/got": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz",
|
||||
"integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^5.2.0",
|
||||
"@szmarczak/http-timer": "^5.0.1",
|
||||
"cacheable-lookup": "^7.0.0",
|
||||
"cacheable-request": "^10.2.8",
|
||||
"decompress-response": "^6.0.0",
|
||||
"form-data-encoder": "^2.1.2",
|
||||
"get-stream": "^6.0.1",
|
||||
"http2-wrapper": "^2.1.10",
|
||||
"lowercase-keys": "^3.0.0",
|
||||
"p-cancelable": "^3.0.0",
|
||||
"responselike": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/got?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/got/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/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
|
@ -4271,9 +4113,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/import-meta-resolve": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz",
|
||||
"integrity": "sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz",
|
||||
"integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
|
@ -8616,20 +8458,20 @@
|
|||
}
|
||||
},
|
||||
"node_modules/webdriver": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.24.6.tgz",
|
||||
"integrity": "sha512-k5XI2/SHd/14h4ElPQH8EzSUXujZIGbBEi+3dTS2H457KFR5Q8QYfIazDs/YnEdooOp8b6Oe9N7qI99LP8K6bQ==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.24.12.tgz",
|
||||
"integrity": "sha512-03DQIClHoaAqTsmDkxGwo4HwHfkn9LzJ1wfNyUerzKg8DnyXeiT6ILqj6EXLfsvh5zddU2vhYGLFXSerPgkuOQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0",
|
||||
"@types/ws": "^8.5.3",
|
||||
"@wdio/config": "8.24.6",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/protocols": "8.23.0",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/utils": "8.24.6",
|
||||
"@wdio/config": "8.24.12",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/protocols": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"@wdio/utils": "8.24.12",
|
||||
"deepmerge-ts": "^5.1.0",
|
||||
"got": "^ 12.6.1",
|
||||
"got": "^12.6.1",
|
||||
"ky": "^0.33.0",
|
||||
"ws": "^8.8.0"
|
||||
},
|
||||
|
@ -8675,25 +8517,25 @@
|
|||
}
|
||||
},
|
||||
"node_modules/webdriverio": {
|
||||
"version": "8.24.6",
|
||||
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.24.6.tgz",
|
||||
"integrity": "sha512-gJMAJiErbXe/oFJbV+H9lXp9GPxnUgHrbtxkG6SCKQlk1zPFho9FZ3fQWl/ty84w5n9ZMhAdnQIfZM9aytxIBQ==",
|
||||
"version": "8.24.12",
|
||||
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.24.12.tgz",
|
||||
"integrity": "sha512-Ddu0NNRMVkTzRzqvm3m0wt2eLUn+Plz2Cj+1QXDnVpddYJvk9J3elZC2hqNyscEtecQ+h2y3r36OcJqkl9jPag==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^20.1.0",
|
||||
"@wdio/config": "8.24.6",
|
||||
"@wdio/logger": "8.16.17",
|
||||
"@wdio/protocols": "8.23.0",
|
||||
"@wdio/repl": "8.23.1",
|
||||
"@wdio/types": "8.24.2",
|
||||
"@wdio/utils": "8.24.6",
|
||||
"@wdio/config": "8.24.12",
|
||||
"@wdio/logger": "8.24.12",
|
||||
"@wdio/protocols": "8.24.12",
|
||||
"@wdio/repl": "8.24.12",
|
||||
"@wdio/types": "8.24.12",
|
||||
"@wdio/utils": "8.24.12",
|
||||
"archiver": "^6.0.0",
|
||||
"aria-query": "^5.0.0",
|
||||
"css-shorthand-properties": "^1.1.1",
|
||||
"css-value": "^0.0.1",
|
||||
"devtools-protocol": "^0.0.1213968",
|
||||
"devtools-protocol": "^0.0.1233178",
|
||||
"grapheme-splitter": "^1.0.2",
|
||||
"import-meta-resolve": "^3.0.0",
|
||||
"import-meta-resolve": "^4.0.0",
|
||||
"is-plain-obj": "^4.1.0",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lodash.zip": "^4.2.0",
|
||||
|
@ -8703,7 +8545,7 @@
|
|||
"resq": "^1.9.1",
|
||||
"rgb2hex": "0.2.5",
|
||||
"serialize-error": "^11.0.1",
|
||||
"webdriver": "8.24.6"
|
||||
"webdriver": "8.24.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.13 || >=18"
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||
"@typescript-eslint/parser": "^6.13.1",
|
||||
"@wdio/cli": "^8.24.6",
|
||||
"@wdio/local-runner": "^8.24.6",
|
||||
"@wdio/mocha-framework": "^8.24.6",
|
||||
"@wdio/spec-reporter": "^8.24.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"@wdio/cli": "^8.24.13",
|
||||
"@wdio/local-runner": "^8.24.12",
|
||||
"@wdio/mocha-framework": "^8.24.12",
|
||||
"@wdio/spec-reporter": "^8.24.12",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-plugin-sonarjs": "^0.23.0",
|
||||
|
|
206
web/package-lock.json
generated
206
web/package-lock.json
generated
|
@ -17,22 +17,22 @@
|
|||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.5.3",
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@goauthentik/api": "^2023.10.4-1700591367",
|
||||
"@goauthentik/api": "^2023.10.4-1701882394",
|
||||
"@lit-labs/context": "^0.4.0",
|
||||
"@lit-labs/task": "^3.1.0",
|
||||
"@lit/localize": "^0.11.4",
|
||||
"@open-wc/lit-helpers": "^0.6.0",
|
||||
"@patternfly/elements": "^2.4.0",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.84.0",
|
||||
"@sentry/tracing": "^7.84.0",
|
||||
"@sentry/browser": "^7.85.0",
|
||||
"@sentry/tracing": "^7.85.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.4.0",
|
||||
"chart.js": "^4.4.1",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.33.3",
|
||||
"core-js": "^3.34.0",
|
||||
"country-flag-icons": "^1.5.9",
|
||||
"fuse.js": "^7.0.0",
|
||||
"lit": "^2.8.0",
|
||||
|
@ -70,8 +70,8 @@
|
|||
"@types/chart.js": "^2.9.41",
|
||||
"@types/codemirror": "5.60.15",
|
||||
"@types/grecaptcha": "^3.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||
"@typescript-eslint/parser": "^6.13.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
|
@ -2944,9 +2944,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@goauthentik/api": {
|
||||
"version": "2023.10.4-1700591367",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2023.10.4-1700591367.tgz",
|
||||
"integrity": "sha512-ljC/SHH6ZgGC2qjvuA3gley8sRz9wVzr5FgRGKeqd1mi6G6TfnFYeA7tuuqgQc6WGN2MVMG17FnBraTI77Rl/A=="
|
||||
"version": "2023.10.4-1701882394",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2023.10.4-1701882394.tgz",
|
||||
"integrity": "sha512-rYfJRl4IGQN6OGdWy6f+yMuNRPgmPjkPTI+6V1otR5NwgKrvZeEzy/8Vx1tEkz3CIix8rgZCmu3SmJVsep0ggQ=="
|
||||
},
|
||||
"node_modules/@hcaptcha/types": {
|
||||
"version": "1.0.3",
|
||||
|
@ -4768,85 +4768,99 @@
|
|||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@sentry-internal/tracing": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.84.0.tgz",
|
||||
"integrity": "sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ==",
|
||||
"node_modules/@sentry-internal/feedback": {
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.85.0.tgz",
|
||||
"integrity": "sha512-MlbIN+N8CWFJBjbqMmARe4+UPo9QRhRar0YoOfmNA2Xqk/EwXcjHWkealosHznXH7tqVbjB25QJpHtDystft/Q==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.84.0",
|
||||
"@sentry/types": "7.84.0",
|
||||
"@sentry/utils": "7.84.0"
|
||||
"@sentry/core": "7.85.0",
|
||||
"@sentry/types": "7.85.0",
|
||||
"@sentry/utils": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/tracing": {
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.85.0.tgz",
|
||||
"integrity": "sha512-p3YMUwkPCy2su9cm/3+7QYR4RiMI0+07DU1BZtht9NLTzY2O87/yvUbn1v2yHR3vJQTy/+7N0ud9/mPBFznRQQ==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.85.0",
|
||||
"@sentry/types": "7.85.0",
|
||||
"@sentry/utils": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/browser": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.84.0.tgz",
|
||||
"integrity": "sha512-X50TlTKY9WzAnHsYc4FYrCWgm+CdVo0h02ggmodVBUpRLUBjj+cs5Q1plov/v/XeorSwmorNEMUu/n+XZNSsrA==",
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.85.0.tgz",
|
||||
"integrity": "sha512-x4sH7vTQnZQgy1U7NuN8XwhleAw7YMQitccHeC5m+kpIKGUO7w4Mdvu8rD3dnjmVmZvASpnwocAxy57/vCU6Ww==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.84.0",
|
||||
"@sentry/core": "7.84.0",
|
||||
"@sentry/replay": "7.84.0",
|
||||
"@sentry/types": "7.84.0",
|
||||
"@sentry/utils": "7.84.0"
|
||||
"@sentry-internal/feedback": "7.85.0",
|
||||
"@sentry-internal/tracing": "7.85.0",
|
||||
"@sentry/core": "7.85.0",
|
||||
"@sentry/replay": "7.85.0",
|
||||
"@sentry/types": "7.85.0",
|
||||
"@sentry/utils": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.84.0.tgz",
|
||||
"integrity": "sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA==",
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.85.0.tgz",
|
||||
"integrity": "sha512-DFDAc4tWmHN5IWhr7XbHCiyF1Xgb95jz8Uj/JTX9atlgodId1UIbER77qpEmH3eQGid/QBdqrlR98zCixgSbwg==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.84.0",
|
||||
"@sentry/utils": "7.84.0"
|
||||
"@sentry/types": "7.85.0",
|
||||
"@sentry/utils": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/replay": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.84.0.tgz",
|
||||
"integrity": "sha512-c4PxT0ZpvkR9zXNfmAk3ojkm6eZ9+NlDze09RFBOCNo69QwIN90hnvbjXFC1+vRIJsfgo78Zr0ya/Wzb3Rog7Q==",
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.85.0.tgz",
|
||||
"integrity": "sha512-zVtTKfO+lu5qTwHpETI/oGo8hU3rdKHr3CdI1vRLw+d60PcAa/pWVlXsQeLRTw8PFwE358gHcpFZezj/11afew==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.84.0",
|
||||
"@sentry/core": "7.84.0",
|
||||
"@sentry/types": "7.84.0",
|
||||
"@sentry/utils": "7.84.0"
|
||||
"@sentry-internal/tracing": "7.85.0",
|
||||
"@sentry/core": "7.85.0",
|
||||
"@sentry/types": "7.85.0",
|
||||
"@sentry/utils": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/tracing": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.84.0.tgz",
|
||||
"integrity": "sha512-NhBX28vUmCu/5avyGKX6B4UTm4MTOfbdg9ZzCnS7hPuWDfEAUIVHZVryi2q8bqp2DNGJvS9qIq/TSf39JIpdJg==",
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.85.0.tgz",
|
||||
"integrity": "sha512-L3bpqiM+zu5f3o6zh6hx3xEzVENyhrkuMlpUOyDo0mUytqp763HqF1xz+R+trzze7R5VWrxJaRPARsCKlXu4Ig==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.84.0"
|
||||
"@sentry-internal/tracing": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/types": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.84.0.tgz",
|
||||
"integrity": "sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA==",
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.85.0.tgz",
|
||||
"integrity": "sha512-R5jR4XkK5tBU2jDiPdSVqzkmjYRr666bcGaFGUHB/xDQCjPsjk+pEmCCL+vpuWoaZmQJUE1hVU7rgnVX81w8zg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils": {
|
||||
"version": "7.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.84.0.tgz",
|
||||
"integrity": "sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ==",
|
||||
"version": "7.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.85.0.tgz",
|
||||
"integrity": "sha512-JZ7seNOLvhjAQ8GeB3GYknPQJkuhF88xAYOaESZP3xPOWBMFUN+IO4RqjMqMLFDniOwsVQS7GB/MfP+hxufieg==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.84.0"
|
||||
"@sentry/types": "7.85.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
@ -10526,16 +10540,16 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.1.tgz",
|
||||
"integrity": "sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz",
|
||||
"integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.1",
|
||||
"@typescript-eslint/type-utils": "6.13.1",
|
||||
"@typescript-eslint/utils": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.2",
|
||||
"@typescript-eslint/type-utils": "6.13.2",
|
||||
"@typescript-eslint/utils": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2",
|
||||
"debug": "^4.3.4",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
|
@ -10594,15 +10608,15 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.1.tgz",
|
||||
"integrity": "sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz",
|
||||
"integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "6.13.1",
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/typescript-estree": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.2",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/typescript-estree": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -10622,13 +10636,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz",
|
||||
"integrity": "sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz",
|
||||
"integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1"
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
|
@ -10639,13 +10653,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz",
|
||||
"integrity": "sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz",
|
||||
"integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "6.13.1",
|
||||
"@typescript-eslint/utils": "6.13.1",
|
||||
"@typescript-eslint/typescript-estree": "6.13.2",
|
||||
"@typescript-eslint/utils": "6.13.2",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
|
@ -10666,9 +10680,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.1.tgz",
|
||||
"integrity": "sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz",
|
||||
"integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
|
@ -10679,13 +10693,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz",
|
||||
"integrity": "sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz",
|
||||
"integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/visitor-keys": "6.13.1",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/visitor-keys": "6.13.2",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
|
@ -10739,17 +10753,17 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.1.tgz",
|
||||
"integrity": "sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz",
|
||||
"integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==",
|
||||
"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.13.1",
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/typescript-estree": "6.13.1",
|
||||
"@typescript-eslint/scope-manager": "6.13.2",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"@typescript-eslint/typescript-estree": "6.13.2",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -10797,12 +10811,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "6.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz",
|
||||
"integrity": "sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==",
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz",
|
||||
"integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.13.1",
|
||||
"@typescript-eslint/types": "6.13.2",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -11687,9 +11701,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz",
|
||||
"integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==",
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
|
||||
"integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
|
@ -12092,9 +12106,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.33.3",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz",
|
||||
"integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==",
|
||||
"version": "3.34.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.34.0.tgz",
|
||||
"integrity": "sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
|
|
@ -38,22 +38,22 @@
|
|||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.5.3",
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@goauthentik/api": "^2023.10.4-1700591367",
|
||||
"@goauthentik/api": "^2023.10.4-1701882394",
|
||||
"@lit-labs/context": "^0.4.0",
|
||||
"@lit-labs/task": "^3.1.0",
|
||||
"@lit/localize": "^0.11.4",
|
||||
"@open-wc/lit-helpers": "^0.6.0",
|
||||
"@patternfly/elements": "^2.4.0",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.84.0",
|
||||
"@sentry/tracing": "^7.84.0",
|
||||
"@sentry/browser": "^7.85.0",
|
||||
"@sentry/tracing": "^7.85.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.4.0",
|
||||
"chart.js": "^4.4.1",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.33.3",
|
||||
"core-js": "^3.34.0",
|
||||
"country-flag-icons": "^1.5.9",
|
||||
"fuse.js": "^7.0.0",
|
||||
"lit": "^2.8.0",
|
||||
|
@ -91,8 +91,8 @@
|
|||
"@types/chart.js": "^2.9.41",
|
||||
"@types/codemirror": "5.60.15",
|
||||
"@types/grecaptcha": "^3.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||
"@typescript-eslint/parser": "^6.13.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||
"@typescript-eslint/parser": "^6.13.2",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
|
|
|
@ -89,17 +89,15 @@ export class ApplicationListPage extends TablePage<Application> {
|
|||
];
|
||||
}
|
||||
|
||||
renderSectionBefore(): TemplateResult {
|
||||
return html`<ak-application-wizard-hint></ak-application-wizard-hint>`;
|
||||
}
|
||||
|
||||
renderSidebarAfter(): TemplateResult {
|
||||
// Rendering the wizard with .open here, as if we set the attribute in
|
||||
// renderObjectCreate() it'll open two wizards, since that function gets called twice
|
||||
|
||||
/* Re-enable the wizard later:
|
||||
<ak-application-wizard
|
||||
.open=${getURLParam("createWizard", false)}
|
||||
.showButton=${false}
|
||||
></ak-application-wizard>*/
|
||||
|
||||
return html` <div class="pf-c-sidebar__panel pf-m-width-25">
|
||||
return html`<div class="pf-c-sidebar__panel pf-m-width-25">
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__body">
|
||||
<ak-markdown .md=${MDApplication}></ak-markdown>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { WizardPanel } from "@goauthentik/components/ak-wizard-main/types";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { KeyUnknown, serializeForm } from "@goauthentik/elements/forms/Form";
|
||||
import { HorizontalFormElement } from "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { consume } from "@lit-labs/context";
|
||||
|
@ -10,6 +12,15 @@ import { styles as AwadStyles } from "./BasePanel.css";
|
|||
import { applicationWizardContext } from "./ContextIdentity";
|
||||
import type { ApplicationWizardState, ApplicationWizardStateUpdate } from "./types";
|
||||
|
||||
/**
|
||||
* Application Wizard Base Panel
|
||||
*
|
||||
* All of the displays in our system inherit from this object, which supplies the basic CSS for all
|
||||
* the inputs we display, as well as the values and validity state for the form currently being
|
||||
* displayed.
|
||||
*
|
||||
*/
|
||||
|
||||
export class ApplicationWizardPageBase
|
||||
extends CustomEmitterElement(AKElement)
|
||||
implements WizardPanel
|
||||
|
@ -18,15 +29,41 @@ export class ApplicationWizardPageBase
|
|||
return AwadStyles;
|
||||
}
|
||||
|
||||
@query("form")
|
||||
form!: HTMLFormElement;
|
||||
|
||||
rendered = false;
|
||||
|
||||
@consume({ context: applicationWizardContext })
|
||||
public wizard!: ApplicationWizardState;
|
||||
|
||||
// This used to be more complex; now it just establishes the event name.
|
||||
@query("form")
|
||||
form!: HTMLFormElement;
|
||||
|
||||
/**
|
||||
* Provide access to the values on the current form. Child implementations use this to craft the
|
||||
* update that will be sent using `dispatchWizardUpdate` below.
|
||||
*/
|
||||
get formValues(): KeyUnknown | undefined {
|
||||
const elements = [
|
||||
...Array.from(
|
||||
this.form.querySelectorAll<HorizontalFormElement>("ak-form-element-horizontal"),
|
||||
),
|
||||
...Array.from(this.form.querySelectorAll<HTMLElement>("[data-ak-control=true]")),
|
||||
];
|
||||
return serializeForm(elements as unknown as NodeListOf<HorizontalFormElement>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide access to the validity of the current form. Child implementations use this to craft
|
||||
* the update that will be sent using `dispatchWizardUpdate` below.
|
||||
*/
|
||||
get valid() {
|
||||
return this.form.checkValidity();
|
||||
}
|
||||
|
||||
rendered = false;
|
||||
|
||||
/**
|
||||
* Provide a single source of truth for the token used to notify the orchestrator that an event
|
||||
* happens. The token `ak-wizard-update` is used by the Wizard framework's reactive controller
|
||||
* to route "data on the current step has changed" events to the orchestrator.
|
||||
*/
|
||||
dispatchWizardUpdate(update: ApplicationWizardStateUpdate) {
|
||||
this.dispatchCustomEvent("ak-wizard-update", update);
|
||||
}
|
||||
|
|
|
@ -5,5 +5,3 @@ import { ApplicationWizardState } from "./types";
|
|||
export const applicationWizardContext = createContext<ApplicationWizardState>(
|
||||
Symbol("ak-application-wizard-state-context"),
|
||||
);
|
||||
|
||||
export default applicationWizardContext;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { merge } from "@goauthentik/common/merge";
|
||||
import { AkWizard } from "@goauthentik/components/ak-wizard-main/AkWizard";
|
||||
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
|
@ -6,7 +5,7 @@ import { ContextProvider } from "@lit-labs/context";
|
|||
import { msg } from "@lit/localize";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
|
||||
import applicationWizardContext from "./ContextIdentity";
|
||||
import { applicationWizardContext } from "./ContextIdentity";
|
||||
import { newSteps } from "./steps";
|
||||
import {
|
||||
ApplicationStep,
|
||||
|
@ -15,10 +14,11 @@ import {
|
|||
OneOfProvider,
|
||||
} from "./types";
|
||||
|
||||
const freshWizardState = () => ({
|
||||
const freshWizardState = (): ApplicationWizardState => ({
|
||||
providerModel: "",
|
||||
app: {},
|
||||
provider: {},
|
||||
errors: {},
|
||||
});
|
||||
|
||||
@customElement("ak-application-wizard")
|
||||
|
@ -56,28 +56,6 @@ export class ApplicationWizard extends CustomListenerElement(
|
|||
*/
|
||||
providerCache: Map<string, OneOfProvider> = new Map();
|
||||
|
||||
maybeProviderSwap(providerModel: string | undefined): boolean {
|
||||
if (
|
||||
providerModel === undefined ||
|
||||
typeof providerModel !== "string" ||
|
||||
providerModel === this.wizardState.providerModel
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.providerCache.set(this.wizardState.providerModel, this.wizardState.provider);
|
||||
const prevProvider = this.providerCache.get(providerModel);
|
||||
this.wizardState.provider = prevProvider ?? {
|
||||
name: `Provider for ${this.wizardState.app.name}`,
|
||||
};
|
||||
const method = this.steps.find(({ id }) => id === "provider-details");
|
||||
if (!method) {
|
||||
throw new Error("Could not find Authentication Method page?");
|
||||
}
|
||||
method.disabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// And this is where all the special cases go...
|
||||
handleUpdate(detail: ApplicationWizardStateUpdate) {
|
||||
if (detail.status === "submitted") {
|
||||
|
@ -87,17 +65,26 @@ export class ApplicationWizard extends CustomListenerElement(
|
|||
}
|
||||
|
||||
this.step.valid = this.step.valid || detail.status === "valid";
|
||||
|
||||
const update = detail.update;
|
||||
|
||||
if (!update) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.maybeProviderSwap(update.providerModel)) {
|
||||
this.requestUpdate();
|
||||
// When the providerModel enum changes, retrieve the customer's prior work for *this* wizard
|
||||
// session (and only this wizard session) or provide an empty model with a default provider
|
||||
// name.
|
||||
if (update.providerModel && update.providerModel !== this.wizardState.providerModel) {
|
||||
const requestedProvider = this.providerCache.get(update.providerModel) ?? {
|
||||
name: `Provider for ${this.wizardState.app.name}`,
|
||||
};
|
||||
if (this.wizardState.providerModel) {
|
||||
this.providerCache.set(this.wizardState.providerModel, this.wizardState.provider);
|
||||
}
|
||||
update.provider = requestedProvider;
|
||||
}
|
||||
|
||||
this.wizardState = merge(this.wizardState, update) as ApplicationWizardState;
|
||||
this.wizardState = update as ApplicationWizardState;
|
||||
this.wizardStateProvider.setValue(this.wizardState);
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
|
30
web/src/admin/applications/wizard/ak-wizard-title.ts
Normal file
30
web/src/admin/applications/wizard/ak-wizard-title.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { css, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||
|
||||
@customElement("ak-wizard-title")
|
||||
export class AkWizardTitle extends AKElement {
|
||||
static get styles() {
|
||||
return [
|
||||
PFContent,
|
||||
PFTitle,
|
||||
css`
|
||||
.ak-bottom-spacing {
|
||||
padding-bottom: var(--pf-global--spacer--lg);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<div class="ak-bottom-spacing pf-c-content">
|
||||
<h3><slot></slot></h3>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default AkWizardTitle;
|
|
@ -5,7 +5,6 @@ import "@goauthentik/components/ak-slug-input";
|
|||
import "@goauthentik/components/ak-switch-input";
|
||||
import "@goauthentik/components/ak-text-input";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
|
@ -17,28 +16,20 @@ import BasePanel from "../BasePanel";
|
|||
|
||||
@customElement("ak-application-wizard-application-details")
|
||||
export class ApplicationWizardApplicationDetails extends BasePanel {
|
||||
handleChange(ev: Event) {
|
||||
if (!ev.target) {
|
||||
console.warn(`Received event with no target: ${ev}`);
|
||||
return;
|
||||
handleChange(_ev: Event) {
|
||||
const formValues = this.formValues;
|
||||
if (!formValues) {
|
||||
throw new Error("No application values on form?");
|
||||
}
|
||||
|
||||
const target = ev.target as HTMLInputElement;
|
||||
const value = target.type === "checkbox" ? target.checked : target.value;
|
||||
this.dispatchWizardUpdate({
|
||||
update: {
|
||||
app: {
|
||||
[target.name]: value,
|
||||
...this.wizard,
|
||||
app: formValues,
|
||||
},
|
||||
},
|
||||
status: this.form.checkValidity() ? "valid" : "invalid",
|
||||
status: this.valid ? "valid" : "invalid",
|
||||
});
|
||||
}
|
||||
|
||||
validator() {
|
||||
return this.form.reportValidity();
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html` <form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
|
@ -48,6 +39,7 @@ export class ApplicationWizardApplicationDetails extends BasePanel {
|
|||
required
|
||||
help=${msg("Application's display Name.")}
|
||||
id="ak-application-wizard-details-name"
|
||||
.errorMessages=${this.wizard.errors.app?.name ?? []}
|
||||
></ak-text-input>
|
||||
<ak-slug-input
|
||||
name="slug"
|
||||
|
@ -56,11 +48,13 @@ export class ApplicationWizardApplicationDetails extends BasePanel {
|
|||
source="#ak-application-wizard-details-name"
|
||||
required
|
||||
help=${msg("Internal application name used in URLs.")}
|
||||
.errorMessages=${this.wizard.errors.app?.slug ?? []}
|
||||
></ak-slug-input>
|
||||
<ak-text-input
|
||||
name="group"
|
||||
value=${ifDefined(this.wizard.app?.group)}
|
||||
label=${msg("Group")}
|
||||
.errorMessages=${this.wizard.errors.app?.group ?? []}
|
||||
help=${msg(
|
||||
"Optionally enter a group name. Applications with identical groups are shown grouped together.",
|
||||
)}
|
||||
|
@ -71,6 +65,7 @@ export class ApplicationWizardApplicationDetails extends BasePanel {
|
|||
name="policyEngineMode"
|
||||
.options=${policyOptions}
|
||||
.value=${this.wizard.app?.policyEngineMode}
|
||||
.errorMessages=${this.wizard.errors.app?.policyEngineMode ?? []}
|
||||
></ak-radio-input>
|
||||
<ak-form-group aria-label="UI Settings">
|
||||
<span slot="header"> ${msg("UI Settings")} </span>
|
||||
|
@ -82,6 +77,7 @@ export class ApplicationWizardApplicationDetails extends BasePanel {
|
|||
help=${msg(
|
||||
"If left empty, authentik will try to extract the launch URL based on the selected provider.",
|
||||
)}
|
||||
.errorMessages=${this.wizard.errors.app?.metaLaunchUrl ?? []}
|
||||
></ak-text-input>
|
||||
<ak-switch-input
|
||||
name="openInNewTab"
|
||||
|
|
|
@ -19,13 +19,17 @@ type ProviderRenderer = () => TemplateResult;
|
|||
|
||||
type ModelConverter = (provider: OneOfProvider) => ModelRequest;
|
||||
|
||||
/**
|
||||
* There's an internal key and an API key because "Proxy" has three different subtypes.
|
||||
*/
|
||||
// prettier-ignore
|
||||
type ProviderType = [
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
ProviderRenderer,
|
||||
ProviderModelEnumType,
|
||||
ModelConverter,
|
||||
string, // internal key used by the wizard to distinguish between providers
|
||||
string, // Name of the provider
|
||||
string, // Description
|
||||
ProviderRenderer, // Function that returns the provider's wizard panel as a TemplateResult
|
||||
ProviderModelEnumType, // key used by the API to distinguish between providers
|
||||
ModelConverter, // Handler that takes a generic provider and returns one specifically typed to its panel
|
||||
];
|
||||
|
||||
export type LocalTypeCreate = TypeCreate & {
|
||||
|
|
|
@ -25,19 +25,15 @@ export class ApplicationWizardAuthenticationMethodChoice extends BasePanel {
|
|||
handleChoice(ev: InputEvent) {
|
||||
const target = ev.target as HTMLInputElement;
|
||||
this.dispatchWizardUpdate({
|
||||
update: { providerModel: target.value },
|
||||
status: this.validator() ? "valid" : "invalid",
|
||||
update: {
|
||||
...this.wizard,
|
||||
providerModel: target.value,
|
||||
errors: {},
|
||||
},
|
||||
status: this.valid ? "valid" : "invalid",
|
||||
});
|
||||
}
|
||||
|
||||
validator() {
|
||||
const radios = Array.from(this.form.querySelectorAll('input[type="radio"]'));
|
||||
const chosen = radios.find(
|
||||
(radio: Element) => radio instanceof HTMLInputElement && radio.checked,
|
||||
);
|
||||
return !!chosen;
|
||||
}
|
||||
|
||||
renderProvider(type: LocalTypeCreate) {
|
||||
const method = this.wizard.providerModel;
|
||||
|
||||
|
|
|
@ -18,12 +18,14 @@ import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
|||
import PFBullseye from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
|
||||
|
||||
import {
|
||||
ApplicationRequest,
|
||||
type ApplicationRequest,
|
||||
CoreApi,
|
||||
TransactionApplicationRequest,
|
||||
TransactionApplicationResponse,
|
||||
type ModelRequest,
|
||||
type TransactionApplicationRequest,
|
||||
type TransactionApplicationResponse,
|
||||
ValidationError,
|
||||
ValidationErrorFromJSON,
|
||||
} from "@goauthentik/api";
|
||||
import type { ModelRequest } from "@goauthentik/api";
|
||||
|
||||
import BasePanel from "../BasePanel";
|
||||
import providerModelsList from "../auth-method-choice/ak-application-wizard-authentication-method-choice.choices";
|
||||
|
@ -88,7 +90,7 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
|||
commitState: State = idleState;
|
||||
|
||||
@state()
|
||||
errors: string[] = [];
|
||||
errors?: ValidationError;
|
||||
|
||||
response?: TransactionApplicationResponse;
|
||||
|
||||
|
@ -121,27 +123,10 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
decodeErrors(body: Record<string, any>) {
|
||||
const spaceify = (src: Record<string, string>) =>
|
||||
Object.values(src).map((msg) => `\u00a0\u00a0\u00a0\u00a0${msg}`);
|
||||
|
||||
let errs: string[] = [];
|
||||
if (body["app"] !== undefined) {
|
||||
errs = [...errs, msg("In the Application:"), ...spaceify(body["app"])];
|
||||
}
|
||||
if (body["provider"] !== undefined) {
|
||||
errs = [...errs, msg("In the Provider:"), ...spaceify(body["provider"])];
|
||||
}
|
||||
console.log(body, errs);
|
||||
return errs;
|
||||
}
|
||||
|
||||
async send(
|
||||
data: TransactionApplicationRequest,
|
||||
): Promise<TransactionApplicationResponse | void> {
|
||||
this.errors = [];
|
||||
|
||||
this.errors = undefined;
|
||||
new CoreApi(DEFAULT_CONFIG)
|
||||
.coreTransactionalApplicationsUpdate({
|
||||
transactionApplicationRequest: data,
|
||||
|
@ -153,18 +138,57 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
|||
this.commitState = successState;
|
||||
})
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
.catch((resolution: any) => {
|
||||
resolution.response.json().then(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(body: Record<string, any>) => {
|
||||
this.errors = this.decodeErrors(body);
|
||||
.catch(async (resolution: any) => {
|
||||
const errors = (this.errors = ValidationErrorFromJSON(
|
||||
await resolution.response.json(),
|
||||
));
|
||||
this.dispatchWizardUpdate({
|
||||
update: {
|
||||
...this.wizard,
|
||||
errors,
|
||||
},
|
||||
);
|
||||
status: "failed",
|
||||
});
|
||||
this.commitState = errorState;
|
||||
});
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
renderErrors(errors?: ValidationError) {
|
||||
if (!errors) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const navTo = (step: number) => () =>
|
||||
this.dispatchCustomEvent("ak-wizard-nav", {
|
||||
command: "goto",
|
||||
step,
|
||||
});
|
||||
|
||||
if (errors.app) {
|
||||
return html`<p>${msg("There was an error in the application.")}</p>
|
||||
<p><a @click=${navTo(0)}>${msg("Review the application.")}</a></p>`;
|
||||
}
|
||||
if (errors.provider) {
|
||||
return html`<p>${msg("There was an error in the provider.")}</p>
|
||||
<p><a @click=${navTo(2)}>${msg("Review the provider.")}</a></p>`;
|
||||
}
|
||||
if (errors.detail) {
|
||||
return html`<p>${msg("There was an error")}: ${errors.detail}</p>`;
|
||||
}
|
||||
if ((errors?.nonFieldErrors ?? []).length > 0) {
|
||||
return html`<p>$(msg("There was an error")}:</p>
|
||||
<ul>
|
||||
${(errors.nonFieldErrors ?? []).map((e: string) => html`<li>${e}</li>`)}
|
||||
</ul>`;
|
||||
}
|
||||
return html`<p>
|
||||
${msg(
|
||||
"There was an error creating the application, but no error message was sent. Please review the server logs.",
|
||||
)}
|
||||
</p>`;
|
||||
}
|
||||
|
||||
render() {
|
||||
const icon = classMap(
|
||||
this.commitState.icon.reduce((acc, icon) => ({ ...acc, [icon]: true }), {}),
|
||||
);
|
||||
|
@ -184,13 +208,7 @@ export class ApplicationWizardCommitApplication extends BasePanel {
|
|||
>
|
||||
${this.commitState.label}
|
||||
</h1>
|
||||
${this.errors.length > 0
|
||||
? html`<ul>
|
||||
${this.errors.map(
|
||||
(msg) => html`<li><code>${msg}</code></li>`,
|
||||
)}
|
||||
</ul>`
|
||||
: nothing}
|
||||
${this.renderErrors(this.errors)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,26 +1,19 @@
|
|||
import BasePanel from "../BasePanel";
|
||||
|
||||
export class ApplicationWizardProviderPageBase extends BasePanel {
|
||||
handleChange(ev: InputEvent) {
|
||||
if (!ev.target) {
|
||||
console.warn(`Received event with no target: ${ev}`);
|
||||
return;
|
||||
handleChange(_ev: InputEvent) {
|
||||
const formValues = this.formValues;
|
||||
if (!formValues) {
|
||||
throw new Error("No provider values on form?");
|
||||
}
|
||||
const target = ev.target as HTMLInputElement;
|
||||
const value = target.type === "checkbox" ? target.checked : target.value;
|
||||
this.dispatchWizardUpdate({
|
||||
update: {
|
||||
provider: {
|
||||
[target.name]: value,
|
||||
...this.wizard,
|
||||
provider: formValues,
|
||||
},
|
||||
},
|
||||
status: this.form.checkValidity() ? "valid" : "invalid",
|
||||
status: this.valid ? "valid" : "invalid",
|
||||
});
|
||||
}
|
||||
|
||||
validator() {
|
||||
return this.form.reportValidity();
|
||||
}
|
||||
}
|
||||
|
||||
export default ApplicationWizardProviderPageBase;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import "@goauthentik/admin/common/ak-core-group-search";
|
||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
|
||||
|
@ -34,12 +35,15 @@ import {
|
|||
export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
||||
render() {
|
||||
const provider = this.wizard.provider as LDAPProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html` <form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
return html` <ak-wizard-title>${msg("Configure LDAP Provider")}</ak-wizard-title>
|
||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
name="name"
|
||||
value=${ifDefined(provider?.name)}
|
||||
label=${msg("Name")}
|
||||
.errorMessages=${errors?.name ?? []}
|
||||
required
|
||||
help=${msg("Method's display Name.")}
|
||||
></ak-text-input>
|
||||
|
@ -48,6 +52,7 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
label=${msg("Bind flow")}
|
||||
?required=${true}
|
||||
name="authorizationFlow"
|
||||
.errorMessages=${errors?.authorizationFlow ?? []}
|
||||
>
|
||||
<ak-tenanted-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
||||
|
@ -55,10 +60,16 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
.tenantFlow=${rootInterface()?.tenant?.flowAuthentication}
|
||||
required
|
||||
></ak-tenanted-flow-search>
|
||||
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used for users to authenticate.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-form-element-horizontal label=${msg("Search group")} name="searchGroup">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Search group")}
|
||||
name="searchGroup"
|
||||
.errorMessages=${errors?.searchGroup ?? []}
|
||||
>
|
||||
<ak-core-group-search
|
||||
name="searchGroup"
|
||||
group=${ifDefined(provider?.searchGroup ?? nothing)}
|
||||
|
@ -80,14 +91,16 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
name="searchMode"
|
||||
.options=${searchModeOptions}
|
||||
.value=${provider?.searchMode}
|
||||
help=${msg("Configure how the outpost queries the core authentik server's users.")}
|
||||
help=${msg(
|
||||
"Configure how the outpost queries the core authentik server's users.",
|
||||
)}
|
||||
>
|
||||
</ak-radio-input>
|
||||
|
||||
<ak-switch-input
|
||||
name="openInNewTab"
|
||||
label=${msg("Code-based MFA Support")}
|
||||
?checked=${provider?.mfaSupport}
|
||||
?checked=${provider?.mfaSupport ?? true}
|
||||
help=${mfaSupportHelp}
|
||||
>
|
||||
</ak-switch-input>
|
||||
|
@ -100,13 +113,18 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
label=${msg("Base DN")}
|
||||
required
|
||||
value="${first(provider?.baseDn, "DC=ldap,DC=goauthentik,DC=io")}"
|
||||
.errorMessages=${errors?.baseDn ?? []}
|
||||
help=${msg(
|
||||
"LDAP DN under which bind requests and search requests can be made.",
|
||||
)}
|
||||
>
|
||||
</ak-text-input>
|
||||
|
||||
<ak-form-element-horizontal label=${msg("Certificate")} name="certificate">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Certificate")}
|
||||
name="certificate"
|
||||
.errorMessages=${errors?.certificate ?? []}
|
||||
>
|
||||
<ak-crypto-certificate-search
|
||||
certificate=${ifDefined(provider?.certificate ?? nothing)}
|
||||
name="certificate"
|
||||
|
@ -119,6 +137,7 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
label=${msg("TLS Server name")}
|
||||
name="tlsServerName"
|
||||
value="${first(provider?.tlsServerName, "")}"
|
||||
.errorMessages=${errors?.tlsServerName ?? []}
|
||||
help=${tlsServerNameHelp}
|
||||
></ak-text-input>
|
||||
|
||||
|
@ -127,6 +146,7 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
required
|
||||
name="uidStartNumber"
|
||||
value="${first(provider?.uidStartNumber, 2000)}"
|
||||
.errorMessages=${errors?.uidStartNumber ?? []}
|
||||
help=${uidStartNumberHelp}
|
||||
></ak-number-input>
|
||||
|
||||
|
@ -135,6 +155,7 @@ export class ApplicationWizardApplicationDetails extends BaseProviderPanel {
|
|||
required
|
||||
name="gidStartNumber"
|
||||
value="${first(provider?.gidStartNumber, 4000)}"
|
||||
.errorMessages=${errors?.gidStartNumber ?? []}
|
||||
help=${gidStartNumberHelp}
|
||||
></ak-number-input>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
|
||||
import {
|
||||
|
@ -27,10 +28,10 @@ import {
|
|||
PropertymappingsApi,
|
||||
SourcesApi,
|
||||
} from "@goauthentik/api";
|
||||
import type {
|
||||
OAuth2Provider,
|
||||
PaginatedOAuthSourceList,
|
||||
PaginatedScopeMappingList,
|
||||
import {
|
||||
type OAuth2Provider,
|
||||
type PaginatedOAuthSourceList,
|
||||
type PaginatedScopeMappingList,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
import BaseProviderPanel from "../BaseProviderPanel";
|
||||
|
@ -38,7 +39,7 @@ import BaseProviderPanel from "../BaseProviderPanel";
|
|||
@customElement("ak-application-wizard-authentication-by-oauth")
|
||||
export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
||||
@state()
|
||||
showClientSecret = false;
|
||||
showClientSecret = true;
|
||||
|
||||
@state()
|
||||
propertyMappings?: PaginatedScopeMappingList;
|
||||
|
@ -68,18 +69,22 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
|
||||
render() {
|
||||
const provider = this.wizard.provider as OAuth2Provider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html`<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
return html`<ak-wizard-title>${msg("Configure OAuth2/OpenId Provider")}</ak-wizard-title>
|
||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
name="name"
|
||||
label=${msg("Name")}
|
||||
value=${ifDefined(provider?.name)}
|
||||
.errorMessages=${errors?.name ?? []}
|
||||
required
|
||||
></ak-text-input>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
name="authenticationFlow"
|
||||
label=${msg("Authentication flow")}
|
||||
.errorMessages=${errors?.authenticationFlow ?? []}
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
||||
|
@ -87,13 +92,15 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
required
|
||||
></ak-flow-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used when a user access this provider and is not authenticated.")}
|
||||
${msg(
|
||||
"Flow used when a user access this provider and is not authenticated.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
name="authorizationFlow"
|
||||
label=${msg("Authorization flow")}
|
||||
.errorMessages=${errors?.authorizationFlow ?? []}
|
||||
?required=${true}
|
||||
>
|
||||
<ak-flow-search
|
||||
|
@ -124,10 +131,8 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
<ak-text-input
|
||||
name="clientId"
|
||||
label=${msg("Client ID")}
|
||||
value="${first(
|
||||
provider?.clientId,
|
||||
randomString(40, ascii_letters + digits),
|
||||
)}"
|
||||
value=${provider?.clientId ?? randomString(40, ascii_letters + digits)}
|
||||
.errorMessages=${errors?.clientId ?? []}
|
||||
required
|
||||
>
|
||||
</ak-text-input>
|
||||
|
@ -135,10 +140,9 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
<ak-text-input
|
||||
name="clientSecret"
|
||||
label=${msg("Client Secret")}
|
||||
value="${first(
|
||||
provider?.clientSecret,
|
||||
randomString(128, ascii_letters + digits),
|
||||
)}"
|
||||
value=${provider?.clientSecret ??
|
||||
randomString(128, ascii_letters + digits)}
|
||||
.errorMessages=${errors?.clientSecret ?? []}
|
||||
?hidden=${!this.showClientSecret}
|
||||
>
|
||||
</ak-text-input>
|
||||
|
@ -147,18 +151,25 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
name="redirectUris"
|
||||
label=${msg("Redirect URIs/Origins (RegEx)")}
|
||||
.value=${provider?.redirectUris}
|
||||
.errorMessages=${errors?.redirectUriHelp ?? []}
|
||||
.bighelp=${redirectUriHelp}
|
||||
>
|
||||
</ak-textarea-input>
|
||||
|
||||
<ak-form-element-horizontal label=${msg("Signing Key")} name="signingKey">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Signing Key")}
|
||||
name="signingKey"
|
||||
.errorMessages=${errors?.signingKey ?? []}
|
||||
>
|
||||
<ak-crypto-certificate-search
|
||||
certificate=${ifDefined(provider?.signingKey ?? nothing)}
|
||||
name="certificate"
|
||||
singleton
|
||||
>
|
||||
</ak-crypto-certificate-search>
|
||||
<p class="pf-c-form__helper-text">${msg("Key used to sign the tokens.")}</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Key used to sign the tokens.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
|
@ -171,6 +182,7 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
label=${msg("Access code validity")}
|
||||
required
|
||||
value="${first(provider?.accessCodeValidity, "minutes=1")}"
|
||||
.errorMessages=${errors?.accessCodeValidity ?? []}
|
||||
.bighelp=${html`<p class="pf-c-form__helper-text">
|
||||
${msg("Configure how long access codes are valid for.")}
|
||||
</p>
|
||||
|
@ -183,6 +195,7 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
label=${msg("Access Token validity")}
|
||||
value="${first(provider?.accessTokenValidity, "minutes=5")}"
|
||||
required
|
||||
.errorMessages=${errors?.accessTokenValidity ?? []}
|
||||
.bighelp=${html` <p class="pf-c-form__helper-text">
|
||||
${msg("Configure how long access tokens are valid for.")}
|
||||
</p>
|
||||
|
@ -194,6 +207,7 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
name="refreshTokenValidity"
|
||||
label=${msg("Refresh Token validity")}
|
||||
value="${first(provider?.refreshTokenValidity, "days=30")}"
|
||||
.errorMessages=${errors?.refreshTokenValidity ?? []}
|
||||
?required=${true}
|
||||
.bighelp=${html` <p class="pf-c-form__helper-text">
|
||||
${msg("Configure how long refresh tokens are valid for.")}
|
||||
|
@ -202,7 +216,11 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
>
|
||||
</ak-text-input>
|
||||
|
||||
<ak-form-element-horizontal label=${msg("Scopes")} name="propertyMappings">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Scopes")}
|
||||
name="propertyMappings"
|
||||
.errorMessages=${errors?.propertyMappings ?? []}
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.propertyMappings?.results.map((scope) => {
|
||||
let selected = false;
|
||||
|
@ -212,9 +230,11 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
"goauthentik.io/providers/oauth2/scope-",
|
||||
) || false;
|
||||
} else {
|
||||
selected = Array.from(provider?.propertyMappings).some((su) => {
|
||||
selected = Array.from(provider?.propertyMappings).some(
|
||||
(su) => {
|
||||
return su == scope.pk;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
return html`<option
|
||||
value=${ifDefined(scope.pk)}
|
||||
|
@ -273,6 +293,7 @@ export class ApplicationWizardAuthenticationByOauth extends BaseProviderPanel {
|
|||
<ak-form-element-horizontal
|
||||
label=${msg("Trusted OIDC Sources")}
|
||||
name="jwksSources"
|
||||
.errorMessages=${errors?.jwksSources ?? []}
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.oauthSources?.results.map((source) => {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { first } from "@goauthentik/common/utils";
|
||||
import "@goauthentik/components/ak-switch-input";
|
||||
|
@ -61,11 +62,11 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
return nothing;
|
||||
}
|
||||
|
||||
renderProxyMode() {
|
||||
return html`<h2>This space intentionally left blank</h2>`;
|
||||
renderProxyMode(): TemplateResult {
|
||||
throw new Error("Must be implemented in a child class.");
|
||||
}
|
||||
|
||||
renderHttpBasic(): TemplateResult {
|
||||
renderHttpBasic() {
|
||||
return html`<ak-text-input
|
||||
name="basicAuthUserAttribute"
|
||||
label=${msg("HTTP-Basic Username Key")}
|
||||
|
@ -87,19 +88,45 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
</ak-text-input>`;
|
||||
}
|
||||
|
||||
scopeMappingConfiguration(provider?: ProxyProvider) {
|
||||
const propertyMappings = this.propertyMappings?.results ?? [];
|
||||
|
||||
const defaultScopes = () =>
|
||||
propertyMappings
|
||||
.filter((scope) => !(scope?.managed ?? "").startsWith("goauthentik.io/providers"))
|
||||
.map((pm) => pm.pk);
|
||||
|
||||
const configuredScopes = (providerMappings: string[]) =>
|
||||
propertyMappings.map((scope) => scope.pk).filter((pk) => providerMappings.includes(pk));
|
||||
|
||||
const scopeValues = provider?.propertyMappings
|
||||
? configuredScopes(provider?.propertyMappings ?? [])
|
||||
: defaultScopes();
|
||||
|
||||
const scopePairs = propertyMappings.map((scope) => [scope.pk, scope.name]);
|
||||
|
||||
return { scopePairs, scopeValues };
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
const errors = this.wizard.errors.provider;
|
||||
const { scopePairs, scopeValues } = this.scopeMappingConfiguration(this.instance);
|
||||
|
||||
return html` <ak-wizard-title>${msg("Configure Proxy Provider")}</ak-wizard-title>
|
||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
${this.renderModeDescription()}
|
||||
<ak-text-input
|
||||
name="name"
|
||||
value=${ifDefined(this.instance?.name)}
|
||||
required
|
||||
.errorMessages=${errors?.name ?? []}
|
||||
label=${msg("Name")}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Authentication flow")}
|
||||
?required=${false}
|
||||
.errorMessages=${errors?.authenticationFlow ?? []}
|
||||
name="authenticationFlow"
|
||||
>
|
||||
<ak-flow-search
|
||||
|
@ -108,7 +135,9 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
required
|
||||
></ak-flow-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used when a user access this provider and is not authenticated.")}
|
||||
${msg(
|
||||
"Flow used when a user access this provider and is not authenticated.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
|
@ -116,6 +145,7 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
label=${msg("Authorization flow")}
|
||||
?required=${true}
|
||||
name="authorizationFlow"
|
||||
.errorMessages=${errors?.authorizationFlow ?? []}
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authorization}
|
||||
|
@ -134,47 +164,40 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
value=${first(this.instance?.accessTokenValidity, "hours=24")}
|
||||
label=${msg("Token validity")}
|
||||
help=${msg("Configure how long tokens are valid for.")}
|
||||
.errorMessages=${errors?.accessTokenValidity ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-form-group>
|
||||
<span slot="header">${msg("Advanced protocol settings")}</span>
|
||||
<div slot="body" class="pf-c-form">
|
||||
<ak-form-element-horizontal label=${msg("Certificate")} name="certificate">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Certificate")}
|
||||
name="certificate"
|
||||
.errorMessages=${errors?.certificate ?? []}
|
||||
>
|
||||
<ak-crypto-certificate-search
|
||||
certificate=${ifDefined(this.instance?.certificate ?? undefined)}
|
||||
></ak-crypto-certificate-search>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Additional scopes")}
|
||||
<ak-multi-select
|
||||
label=${msg("AdditionalScopes")}
|
||||
name="propertyMappings"
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.propertyMappings?.results
|
||||
.filter((scope) => {
|
||||
return !scope.managed?.startsWith("goauthentik.io/providers");
|
||||
})
|
||||
.map((scope) => {
|
||||
const selected = (this.instance?.propertyMappings || []).some(
|
||||
(su) => {
|
||||
return su == scope.pk;
|
||||
},
|
||||
);
|
||||
return html`<option
|
||||
value=${ifDefined(scope.pk)}
|
||||
?selected=${selected}
|
||||
>
|
||||
${scope.name}
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
required
|
||||
.options=${scopePairs}
|
||||
.values=${scopeValues}
|
||||
.errorMessages=${errors?.propertyMappings ?? []}
|
||||
.richhelp=${html`
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Additional scope mappings, which are passed to the proxy.")}
|
||||
${msg(
|
||||
"Additional scope mappings, which are passed to the proxy.",
|
||||
)}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Hold control/command to select multiple items.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
`}
|
||||
></ak-multi-select>
|
||||
|
||||
<ak-textarea-input
|
||||
name="skipPathRegex"
|
||||
|
@ -182,6 +205,7 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
? msg("Unauthenticated URLs")
|
||||
: msg("Unauthenticated Paths")}
|
||||
value=${ifDefined(this.instance?.skipPathRegex)}
|
||||
.errorMessages=${errors?.skipPathRegex ?? []}
|
||||
.bighelp=${html` <p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Regular expressions for which authentication is not required. Each new line is interpreted as a new expression.",
|
||||
|
@ -226,12 +250,15 @@ export class AkTypeProxyApplicationWizardPage extends BaseProviderPanel {
|
|||
<ak-form-element-horizontal
|
||||
label=${msg("Trusted OIDC Sources")}
|
||||
name="jwksSources"
|
||||
.errorMessages=${errors?.jwksSources ?? []}
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.oauthSources?.results.map((source) => {
|
||||
const selected = (this.instance?.jwksSources || []).some((su) => {
|
||||
const selected = (this.instance?.jwksSources || []).some(
|
||||
(su) => {
|
||||
return su == source.pk;
|
||||
});
|
||||
},
|
||||
);
|
||||
return html`<option value=${source.pk} ?selected=${selected}>
|
||||
${source.name} (${source.slug})
|
||||
</option>`;
|
||||
|
|
|
@ -5,6 +5,8 @@ import { customElement } from "@lit/reactive-element/decorators.js";
|
|||
import { html } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { ProxyProvider } from "@goauthentik/api";
|
||||
|
||||
import AkTypeProxyApplicationWizardPage from "./AuthenticationByProxyPage";
|
||||
|
||||
@customElement("ak-application-wizard-authentication-for-forward-proxy-domain")
|
||||
|
@ -28,11 +30,15 @@ export class AkForwardDomainProxyApplicationWizardPage extends AkTypeProxyApplic
|
|||
}
|
||||
|
||||
renderProxyMode() {
|
||||
const provider = this.wizard.provider as ProxyProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html`
|
||||
<ak-text-input
|
||||
name="externalHost"
|
||||
label=${msg("External host")}
|
||||
value=${ifDefined(this.instance?.externalHost)}
|
||||
value=${ifDefined(provider?.externalHost)}
|
||||
.errorMessages=${errors?.externalHost ?? []}
|
||||
required
|
||||
help=${msg(
|
||||
"The external URL you'll authenticate at. The authentik core server should be reachable under this URL.",
|
||||
|
@ -42,7 +48,8 @@ export class AkForwardDomainProxyApplicationWizardPage extends AkTypeProxyApplic
|
|||
<ak-text-input
|
||||
name="cookieDomain"
|
||||
label=${msg("Cookie domain")}
|
||||
value="${ifDefined(this.instance?.cookieDomain)}"
|
||||
value="${ifDefined(provider?.cookieDomain)}"
|
||||
.errorMessages=${errors?.cookieDomain ?? []}
|
||||
required
|
||||
help=${msg(
|
||||
"Set this to the domain you wish the authentication to be valid for. Must be a parent domain of the URL above. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'.",
|
||||
|
|
|
@ -7,6 +7,8 @@ import { customElement } from "@lit/reactive-element/decorators.js";
|
|||
import { html } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { ProxyProvider } from "@goauthentik/api";
|
||||
|
||||
import AkTypeProxyApplicationWizardPage from "./AuthenticationByProxyPage";
|
||||
|
||||
@customElement("ak-application-wizard-authentication-for-reverse-proxy")
|
||||
|
@ -20,25 +22,30 @@ export class AkReverseProxyApplicationWizardPage extends AkTypeProxyApplicationW
|
|||
}
|
||||
|
||||
renderProxyMode() {
|
||||
const provider = this.wizard.provider as ProxyProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html` <ak-text-input
|
||||
name="externalHost"
|
||||
value=${ifDefined(this.instance?.externalHost)}
|
||||
value=${ifDefined(provider?.externalHost)}
|
||||
required
|
||||
label=${msg("External host")}
|
||||
.errorMessages=${errors?.externalHost ?? []}
|
||||
help=${msg(
|
||||
"The external URL you'll access the application at. Include any non-standard port.",
|
||||
)}
|
||||
></ak-text-input>
|
||||
<ak-text-input
|
||||
name="internalHost"
|
||||
value=${ifDefined(this.instance?.internalHost)}
|
||||
value=${ifDefined(provider?.internalHost)}
|
||||
.errorMessages=${errors?.internalHost ?? []}
|
||||
required
|
||||
label=${msg("Internal host")}
|
||||
help=${msg("Upstream host that the requests are forwarded to.")}
|
||||
></ak-text-input>
|
||||
<ak-switch-input
|
||||
name="internalHostSslValidation"
|
||||
?checked=${first(this.instance?.internalHostSslValidation, true)}
|
||||
?checked=${first(provider?.internalHostSslValidation, true)}
|
||||
label=${msg("Internal host SSL Validation")}
|
||||
help=${msg("Validate SSL Certificates of upstream servers.")}
|
||||
>
|
||||
|
|
|
@ -5,6 +5,8 @@ import { customElement } from "@lit/reactive-element/decorators.js";
|
|||
import { html } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { ProxyProvider } from "@goauthentik/api";
|
||||
|
||||
import AkTypeProxyApplicationWizardPage from "./AuthenticationByProxyPage";
|
||||
|
||||
@customElement("ak-application-wizard-authentication-for-single-forward-proxy")
|
||||
|
@ -21,11 +23,15 @@ export class AkForwardSingleProxyApplicationWizardPage extends AkTypeProxyApplic
|
|||
}
|
||||
|
||||
renderProxyMode() {
|
||||
const provider = this.wizard.provider as ProxyProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html`<ak-text-input
|
||||
name="externalHost"
|
||||
value=${ifDefined(this.instance?.externalHost)}
|
||||
value=${ifDefined(provider?.externalHost)}
|
||||
required
|
||||
label=${msg("External host")}
|
||||
.errorMessages=${errors?.externalHost ?? []}
|
||||
help=${msg(
|
||||
"The external URL you'll access the application at. Include any non-standard port.",
|
||||
)}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
|
||||
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
|
||||
|
@ -19,12 +20,15 @@ import BaseProviderPanel from "../BaseProviderPanel";
|
|||
export class ApplicationWizardAuthenticationByRadius extends BaseProviderPanel {
|
||||
render() {
|
||||
const provider = this.wizard.provider as RadiusProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html`<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
return html`<ak-wizard-title>${msg("Configure Radius Provider")}</ak-wizard-title>
|
||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
name="name"
|
||||
label=${msg("Name")}
|
||||
value=${ifDefined(provider?.name)}
|
||||
.errorMessages=${errors?.name ?? []}
|
||||
required
|
||||
>
|
||||
</ak-text-input>
|
||||
|
@ -33,6 +37,7 @@ export class ApplicationWizardAuthenticationByRadius extends BaseProviderPanel {
|
|||
label=${msg("Authentication flow")}
|
||||
?required=${true}
|
||||
name="authorizationFlow"
|
||||
.errorMessages=${errors?.authorizationFlow ?? []}
|
||||
>
|
||||
<ak-tenanted-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
||||
|
@ -40,7 +45,9 @@ export class ApplicationWizardAuthenticationByRadius extends BaseProviderPanel {
|
|||
.tenantFlow=${rootInterface()?.tenant?.flowAuthentication}
|
||||
required
|
||||
></ak-tenanted-flow-search>
|
||||
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used for users to authenticate.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-form-group expanded>
|
||||
|
@ -49,6 +56,7 @@ export class ApplicationWizardAuthenticationByRadius extends BaseProviderPanel {
|
|||
<ak-text-input
|
||||
name="sharedSecret"
|
||||
label=${msg("Shared secret")}
|
||||
.errorMessages=${errors?.sharedSecret ?? []}
|
||||
value=${first(
|
||||
provider?.sharedSecret,
|
||||
randomString(128, ascii_letters + digits),
|
||||
|
@ -59,6 +67,7 @@ export class ApplicationWizardAuthenticationByRadius extends BaseProviderPanel {
|
|||
name="clientNetworks"
|
||||
label=${msg("Client Networks")}
|
||||
value=${first(provider?.clientNetworks, "0.0.0.0/0, ::/0")}
|
||||
.errorMessages=${errors?.clientNetworks ?? []}
|
||||
required
|
||||
help=${msg(`List of CIDRs (comma-seperated) that clients can connect from. A more specific
|
||||
CIDR will match before a looser one. Clients connecting from a non-specified CIDR
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import "@goauthentik/admin/common/ak-core-group-search";
|
||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import "@goauthentik/components/ak-multi-select";
|
||||
import "@goauthentik/components/ak-number-input";
|
||||
import "@goauthentik/components/ak-radio-input";
|
||||
import "@goauthentik/components/ak-switch-input";
|
||||
|
@ -10,7 +13,7 @@ import "@goauthentik/elements/forms/FormGroup";
|
|||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
|
||||
import { customElement, state } from "@lit/reactive-element/decorators.js";
|
||||
import { html } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
|
@ -27,9 +30,11 @@ import {
|
|||
signatureAlgorithmOptions,
|
||||
spBindingOptions,
|
||||
} from "./SamlProviderOptions";
|
||||
import "./saml-property-mappings-search";
|
||||
|
||||
@customElement("ak-application-wizard-authentication-by-saml-configuration")
|
||||
export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPanel {
|
||||
@state()
|
||||
propertyMappings?: PaginatedSAMLPropertyMappingList;
|
||||
|
||||
constructor() {
|
||||
|
@ -43,21 +48,47 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
});
|
||||
}
|
||||
|
||||
propertyMappingConfiguration(provider?: SAMLProvider) {
|
||||
const propertyMappings = this.propertyMappings?.results ?? [];
|
||||
|
||||
const configuredMappings = (providerMappings: string[]) =>
|
||||
propertyMappings.map((pm) => pm.pk).filter((pmpk) => providerMappings.includes(pmpk));
|
||||
|
||||
const managedMappings = () =>
|
||||
propertyMappings
|
||||
.filter((pm) => (pm?.managed ?? "").startsWith("goauthentik.io/providers/saml"))
|
||||
.map((pm) => pm.pk);
|
||||
|
||||
const pmValues = provider?.propertyMappings
|
||||
? configuredMappings(provider?.propertyMappings ?? [])
|
||||
: managedMappings();
|
||||
|
||||
const propertyPairs = propertyMappings.map((pm) => [pm.pk, pm.name]);
|
||||
|
||||
return { pmValues, propertyPairs };
|
||||
}
|
||||
|
||||
render() {
|
||||
const provider = this.wizard.provider as SAMLProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html` <form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
const { pmValues, propertyPairs } = this.propertyMappingConfiguration(provider);
|
||||
|
||||
return html` <ak-wizard-title>${msg("Configure SAML Provider")}</ak-wizard-title>
|
||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
name="name"
|
||||
value=${ifDefined(provider?.name)}
|
||||
required
|
||||
label=${msg("Name")}
|
||||
.errorMessages=${errors?.name ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Authentication flow")}
|
||||
?required=${false}
|
||||
name="authenticationFlow"
|
||||
.errorMessages=${errors?.authenticationFlow ?? []}
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
||||
|
@ -65,7 +96,9 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
required
|
||||
></ak-flow-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used when a user access this provider and is not authenticated.")}
|
||||
${msg(
|
||||
"Flow used when a user access this provider and is not authenticated.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
|
@ -73,6 +106,7 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
label=${msg("Authorization flow")}
|
||||
?required=${true}
|
||||
name="authorizationFlow"
|
||||
.errorMessages=${errors?.authorizationFlow ?? []}
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authorization}
|
||||
|
@ -92,6 +126,7 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
value=${ifDefined(provider?.acsUrl)}
|
||||
required
|
||||
label=${msg("ACS URL")}
|
||||
.errorMessages=${errors?.acsUrl ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-text-input
|
||||
|
@ -100,6 +135,7 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
required
|
||||
label=${msg("Issuer")}
|
||||
help=${msg("Also known as EntityID.")}
|
||||
.errorMessages=${errors?.issuer ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-radio-input
|
||||
|
@ -118,6 +154,7 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
name="audience"
|
||||
value=${ifDefined(provider?.audience)}
|
||||
label=${msg("Audience")}
|
||||
.errorMessages=${errors?.audience ?? []}
|
||||
></ak-text-input>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
|
@ -154,36 +191,19 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Property mappings")}
|
||||
?required=${true}
|
||||
<ak-multi-select
|
||||
label=${msg("Property Mappings")}
|
||||
name="propertyMappings"
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.propertyMappings?.results.map((mapping) => {
|
||||
let selected = false;
|
||||
if (!provider?.propertyMappings) {
|
||||
selected =
|
||||
mapping.managed?.startsWith(
|
||||
"goauthentik.io/providers/saml",
|
||||
) || false;
|
||||
} else {
|
||||
selected = Array.from(provider?.propertyMappings).some((su) => {
|
||||
return su == mapping.pk;
|
||||
});
|
||||
}
|
||||
return html`<option
|
||||
value=${ifDefined(mapping.pk)}
|
||||
?selected=${selected}
|
||||
>
|
||||
${mapping.name}
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
required
|
||||
.options=${propertyPairs}
|
||||
.values=${pmValues}
|
||||
.richhelp=${html` <p class="pf-c-form__helper-text">
|
||||
${msg("Property mappings used for user mapping.")}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Hold control/command to select multiple items.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</p>`}
|
||||
></ak-multi-select>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("NameID Property Mapping")}
|
||||
|
@ -205,7 +225,10 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
value=${provider?.assertionValidNotBefore || "minutes=-5"}
|
||||
required
|
||||
label=${msg("Assertion valid not before")}
|
||||
help=${msg("Configure the maximum allowed time drift for an assertion.")}
|
||||
help=${msg(
|
||||
"Configure the maximum allowed time drift for an assertion.",
|
||||
)}
|
||||
.errorMessages=${errors?.assertionValidNotBefore ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-text-input
|
||||
|
@ -213,7 +236,10 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
value=${provider?.assertionValidNotOnOrAfter || "minutes=5"}
|
||||
required
|
||||
label=${msg("Assertion valid not on or after")}
|
||||
help=${msg("Assertion not valid on or after current time + this value.")}
|
||||
help=${msg(
|
||||
"Assertion not valid on or after current time + this value.",
|
||||
)}
|
||||
.errorMessages=${errors?.assertionValidNotOnOrAfter ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-text-input
|
||||
|
@ -222,6 +248,7 @@ export class ApplicationWizardProviderSamlConfiguration extends BaseProviderPane
|
|||
required
|
||||
label=${msg("Session valid not on or after")}
|
||||
help=${msg("Session not valid on or after current time + this value.")}
|
||||
.errorMessages=${errors?.sessionValidNotOnOrAfter ?? []}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-radio-input
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search-no-default";
|
||||
import "@goauthentik/components/ak-file-input";
|
||||
import { AkFileInput } from "@goauthentik/components/ak-file-input";
|
||||
import "@goauthentik/components/ak-text-input";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { customElement } from "@lit/reactive-element/decorators/custom-element.js";
|
||||
import { html } from "lit";
|
||||
import { query } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import {
|
||||
FlowsInstancesListDesignationEnum,
|
||||
ProvidersSamlImportMetadataCreateRequest,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
import BaseProviderPanel from "../BaseProviderPanel";
|
||||
|
||||
@customElement("ak-application-wizard-authentication-by-saml-import")
|
||||
export class ApplicationWizardProviderSamlImport extends BaseProviderPanel {
|
||||
@query('ak-file-input[name="metadata"]')
|
||||
fileInput!: AkFileInput;
|
||||
|
||||
handleChange(ev: InputEvent) {
|
||||
if (!ev.target) {
|
||||
console.warn(`Received event with no target: ${ev}`);
|
||||
return;
|
||||
}
|
||||
const target = ev.target as HTMLInputElement;
|
||||
if (target.type === "file") {
|
||||
const file = this.fileInput.files?.[0] ?? null;
|
||||
if (file) {
|
||||
this.dispatchWizardUpdate({
|
||||
update: {
|
||||
provider: {
|
||||
file,
|
||||
},
|
||||
},
|
||||
status: this.form.checkValidity() ? "valid" : "invalid",
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.handleChange(ev);
|
||||
}
|
||||
|
||||
render() {
|
||||
const provider = this.wizard.provider as
|
||||
| ProvidersSamlImportMetadataCreateRequest
|
||||
| undefined;
|
||||
|
||||
return html` <form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
name="name"
|
||||
value=${ifDefined(provider?.name)}
|
||||
label=${msg("Name")}
|
||||
required
|
||||
help=${msg("Method's display Name.")}
|
||||
></ak-text-input>
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Authorization flow")}
|
||||
?required=${true}
|
||||
name="authorizationFlow"
|
||||
>
|
||||
<ak-flow-search-no-default
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authorization}
|
||||
required
|
||||
></ak-flow-search-no-default>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used when authorizing this provider.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-file-input name="metadata" label=${msg("Metadata")} required></ak-file-input>
|
||||
</form>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default ApplicationWizardProviderSamlImport;
|
|
@ -1,7 +1,10 @@
|
|||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||
import "@goauthentik/admin/common/ak-core-group-search";
|
||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { first } from "@goauthentik/common/utils";
|
||||
import "@goauthentik/components/ak-multi-select";
|
||||
import "@goauthentik/components/ak-switch-input";
|
||||
import "@goauthentik/components/ak-text-input";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
|
@ -12,14 +15,7 @@ import { customElement, state } from "@lit/reactive-element/decorators.js";
|
|||
import { html } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import {
|
||||
CoreApi,
|
||||
CoreGroupsListRequest,
|
||||
type Group,
|
||||
PaginatedSCIMMappingList,
|
||||
PropertymappingsApi,
|
||||
type SCIMProvider,
|
||||
} from "@goauthentik/api";
|
||||
import { PaginatedSCIMMappingList, PropertymappingsApi, type SCIMProvider } from "@goauthentik/api";
|
||||
|
||||
import BaseProviderPanel from "../BaseProviderPanel";
|
||||
|
||||
|
@ -31,22 +27,52 @@ export class ApplicationWizardAuthenticationBySCIM extends BaseProviderPanel {
|
|||
constructor() {
|
||||
super();
|
||||
new PropertymappingsApi(DEFAULT_CONFIG)
|
||||
.propertymappingsScopeList({
|
||||
ordering: "scope_name",
|
||||
.propertymappingsScimList({
|
||||
ordering: "managed",
|
||||
})
|
||||
.then((propertyMappings: PaginatedSCIMMappingList) => {
|
||||
this.propertyMappings = propertyMappings;
|
||||
});
|
||||
}
|
||||
|
||||
propertyMappingConfiguration(provider?: SCIMProvider) {
|
||||
const propertyMappings = this.propertyMappings?.results ?? [];
|
||||
|
||||
const configuredMappings = (providerMappings: string[]) =>
|
||||
propertyMappings.map((pm) => pm.pk).filter((pmpk) => providerMappings.includes(pmpk));
|
||||
|
||||
const managedMappings = (key: string) =>
|
||||
propertyMappings
|
||||
.filter((pm) => pm.managed === `goauthentik.io/providers/scim/${key}`)
|
||||
.map((pm) => pm.pk);
|
||||
|
||||
const pmUserValues = provider?.propertyMappings
|
||||
? configuredMappings(provider?.propertyMappings ?? [])
|
||||
: managedMappings("user");
|
||||
|
||||
const pmGroupValues = provider?.propertyMappingsGroup
|
||||
? configuredMappings(provider?.propertyMappingsGroup ?? [])
|
||||
: managedMappings("group");
|
||||
|
||||
const propertyPairs = propertyMappings.map((pm) => [pm.pk, pm.name]);
|
||||
|
||||
return { pmUserValues, pmGroupValues, propertyPairs };
|
||||
}
|
||||
|
||||
render() {
|
||||
const provider = this.wizard.provider as SCIMProvider | undefined;
|
||||
const errors = this.wizard.errors.provider;
|
||||
|
||||
return html`<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
const { pmUserValues, pmGroupValues, propertyPairs } =
|
||||
this.propertyMappingConfiguration(provider);
|
||||
|
||||
return html`<ak-wizard-title>${msg("Configure SCIM Provider")}</ak-wizard-title>
|
||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||
<ak-text-input
|
||||
name="name"
|
||||
label=${msg("Name")}
|
||||
value=${ifDefined(provider?.name)}
|
||||
.errorMessages=${errors?.name ?? []}
|
||||
required
|
||||
></ak-text-input>
|
||||
<ak-form-group expanded>
|
||||
|
@ -58,12 +84,14 @@ export class ApplicationWizardAuthenticationBySCIM extends BaseProviderPanel {
|
|||
value="${first(provider?.url, "")}"
|
||||
required
|
||||
help=${msg("SCIM base url, usually ends in /v2.")}
|
||||
.errorMessages=${errors?.url ?? []}
|
||||
>
|
||||
</ak-text-input>
|
||||
<ak-text-input
|
||||
name="token"
|
||||
label=${msg("Token")}
|
||||
value="${first(provider?.token, "")}"
|
||||
.errorMessages=${errors?.token ?? []}
|
||||
required
|
||||
help=${msg(
|
||||
"Token to authenticate with. Currently only bearer authentication is supported.",
|
||||
|
@ -81,31 +109,9 @@ export class ApplicationWizardAuthenticationBySCIM extends BaseProviderPanel {
|
|||
label=${msg("Exclude service accounts")}
|
||||
></ak-switch-input>
|
||||
<ak-form-element-horizontal label=${msg("Group")} name="filterGroup">
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<Group[]> => {
|
||||
const args: CoreGroupsListRequest = {
|
||||
ordering: "name",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const groups = await new CoreApi(DEFAULT_CONFIG).coreGroupsList(
|
||||
args,
|
||||
);
|
||||
return groups.results;
|
||||
}}
|
||||
.renderElement=${(group: Group): string => {
|
||||
return group.name;
|
||||
}}
|
||||
.value=${(group: Group | undefined): string | undefined => {
|
||||
return group ? group.pk : undefined;
|
||||
}}
|
||||
.selected=${(group: Group): boolean => {
|
||||
return group.pk === provider?.filterGroup;
|
||||
}}
|
||||
?blankable=${true}
|
||||
>
|
||||
</ak-search-select>
|
||||
<ak-core-group-search
|
||||
.group=${provider?.filterGroup}
|
||||
></ak-core-group-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Only sync users within the selected group.")}
|
||||
</p>
|
||||
|
@ -115,71 +121,32 @@ export class ApplicationWizardAuthenticationBySCIM extends BaseProviderPanel {
|
|||
<ak-form-group ?expanded=${true}>
|
||||
<span slot="header"> ${msg("Attribute mapping")} </span>
|
||||
<div slot="body" class="pf-c-form">
|
||||
<ak-form-element-horizontal
|
||||
<ak-multi-select
|
||||
label=${msg("User Property Mappings")}
|
||||
?required=${true}
|
||||
required
|
||||
name="propertyMappings"
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.propertyMappings?.results.map((mapping) => {
|
||||
let selected = false;
|
||||
if (!provider?.propertyMappings) {
|
||||
selected =
|
||||
mapping.managed === "goauthentik.io/providers/scim/user" ||
|
||||
false;
|
||||
} else {
|
||||
selected = Array.from(provider?.propertyMappings).some((su) => {
|
||||
return su == mapping.pk;
|
||||
});
|
||||
}
|
||||
return html`<option
|
||||
value=${ifDefined(mapping.pk)}
|
||||
?selected=${selected}
|
||||
>
|
||||
${mapping.name}
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Property mappings used to user mapping.")}
|
||||
.options=${propertyPairs}
|
||||
.values=${pmUserValues}
|
||||
.richhelp=${html` <p class="pf-c-form__helper-text">
|
||||
${msg("Property mappings used for user mapping.")}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Hold control/command to select multiple items.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
</p>`}
|
||||
></ak-multi-select>
|
||||
<ak-multi-select
|
||||
label=${msg("Group Property Mappings")}
|
||||
?required=${true}
|
||||
required
|
||||
name="propertyMappingsGroup"
|
||||
>
|
||||
<select class="pf-c-form-control" multiple>
|
||||
${this.propertyMappings?.results.map((mapping) => {
|
||||
let selected = false;
|
||||
if (!provider?.propertyMappingsGroup) {
|
||||
selected =
|
||||
mapping.managed === "goauthentik.io/providers/scim/group";
|
||||
} else {
|
||||
selected = Array.from(provider?.propertyMappingsGroup).some(
|
||||
(su) => {
|
||||
return su == mapping.pk;
|
||||
},
|
||||
);
|
||||
}
|
||||
return html`<option
|
||||
value=${ifDefined(mapping.pk)}
|
||||
?selected=${selected}
|
||||
>
|
||||
${mapping.name}
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Property mappings used to group creation.")}
|
||||
.options=${propertyPairs}
|
||||
.values=${pmGroupValues}
|
||||
.richhelp=${html` <p class="pf-c-form__helper-text">
|
||||
${msg("Property mappings used for group creation.")}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Hold control/command to select multiple items.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</p>`}
|
||||
></ak-multi-select>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
</form>`;
|
||||
|
|
|
@ -15,6 +15,12 @@ import "./commit/ak-application-wizard-commit-application";
|
|||
import "./methods/ak-application-wizard-authentication-method";
|
||||
import { ApplicationStep as ApplicationStepType } from "./types";
|
||||
|
||||
/**
|
||||
* In the current implementation, all of the child forms have access to the wizard's
|
||||
* global context, into which all data is written, and which is updated by events
|
||||
* flowing into the top-level orchestrator.
|
||||
*/
|
||||
|
||||
class ApplicationStep implements ApplicationStepType {
|
||||
id = "application";
|
||||
label = "Application Details";
|
||||
|
|
|
@ -3,7 +3,7 @@ import { customElement } from "@lit/reactive-element/decorators/custom-element.j
|
|||
import { state } from "@lit/reactive-element/decorators/state.js";
|
||||
import { LitElement, html } from "lit";
|
||||
|
||||
import applicationWizardContext from "../ContextIdentity";
|
||||
import { applicationWizardContext } from "../ContextIdentity";
|
||||
import type { ApplicationWizardState } from "../types";
|
||||
|
||||
@customElement("ak-application-context-display-for-test")
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
type RadiusProviderRequest,
|
||||
type SAMLProviderRequest,
|
||||
type SCIMProviderRequest,
|
||||
type ValidationError,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
export type OneOfProvider =
|
||||
|
@ -24,12 +25,13 @@ export interface ApplicationWizardState {
|
|||
providerModel: string;
|
||||
app: Partial<ApplicationRequest>;
|
||||
provider: OneOfProvider;
|
||||
errors: ValidationError;
|
||||
}
|
||||
|
||||
type StatusType = "invalid" | "valid" | "submitted" | "failed";
|
||||
|
||||
export type ApplicationWizardStateUpdate = {
|
||||
update?: Partial<ApplicationWizardState>;
|
||||
update?: ApplicationWizardState;
|
||||
status?: StatusType;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import "@goauthentik/admin/events/EventVolumeChart";
|
||||
import { EventGeo } from "@goauthentik/admin/events/utils";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { EventWithContext } from "@goauthentik/common/events";
|
||||
|
@ -10,7 +11,7 @@ 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";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import { Event, EventsApi } from "@goauthentik/api";
|
||||
|
@ -35,6 +36,14 @@ export class EventListPage extends TablePage<Event> {
|
|||
@property()
|
||||
order = "-created";
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(css`
|
||||
.pf-m-no-padding-bottom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
async apiEndpoint(page: number): Promise<PaginatedResponse<Event>> {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsEventsList({
|
||||
ordering: this.order,
|
||||
|
@ -55,6 +64,19 @@ export class EventListPage extends TablePage<Event> {
|
|||
];
|
||||
}
|
||||
|
||||
renderSectionBefore(): TemplateResult {
|
||||
return html`
|
||||
<div class="pf-c-page__main-section pf-m-no-padding-bottom">
|
||||
<ak-events-volume-chart
|
||||
.query=${{
|
||||
page: this.page,
|
||||
search: this.search,
|
||||
}}
|
||||
></ak-events-volume-chart>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
row(item: EventWithContext): TemplateResult[] {
|
||||
return [
|
||||
html`<div>${actionToLabel(item.action)}</div>
|
||||
|
|
63
web/src/admin/events/EventVolumeChart.ts
Normal file
63
web/src/admin/events/EventVolumeChart.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { DEFAULT_CONFIG } from "@goauthentik/app/common/api/config";
|
||||
import { AKChart } from "@goauthentik/app/elements/charts/Chart";
|
||||
import { ChartData } from "chart.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
|
||||
import { Coordinate, EventsApi, EventsEventsListRequest } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-events-volume-chart")
|
||||
export class EventVolumeChart extends AKChart<Coordinate[]> {
|
||||
_query?: EventsEventsListRequest;
|
||||
|
||||
@property({ attribute: false })
|
||||
set query(value: EventsEventsListRequest | undefined) {
|
||||
this._query = value;
|
||||
this.refreshHandler();
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(
|
||||
PFCard,
|
||||
css`
|
||||
.pf-c-card__body {
|
||||
height: 12rem;
|
||||
}
|
||||
`,
|
||||
);
|
||||
}
|
||||
|
||||
apiRequest(): Promise<Coordinate[]> {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList(this._query);
|
||||
}
|
||||
|
||||
getChartData(data: Coordinate[]): ChartData {
|
||||
return {
|
||||
datasets: [
|
||||
{
|
||||
label: msg("Events"),
|
||||
backgroundColor: "rgba(189, 229, 184, .5)",
|
||||
spanGaps: true,
|
||||
data:
|
||||
data.map((cord) => {
|
||||
return {
|
||||
x: cord.xCord || 0,
|
||||
y: cord.yCord || 0,
|
||||
};
|
||||
}) || [],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${msg("Event volume")}</div>
|
||||
<div class="pf-c-card__body">${super.render()}</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
/** Taken from: https://github.com/zellwk/javascript/tree/master
|
||||
*
|
||||
* We have added some typescript annotations, but this is such a rich feature with deep nesting
|
||||
* we'll just have to watch it closely for any issues. So far there don't seem to be any.
|
||||
*
|
||||
*/
|
||||
|
||||
function objectType<T>(value: T) {
|
||||
return Object.prototype.toString.call(value);
|
||||
}
|
||||
|
||||
// Creates a deep clone for each value
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function cloneDescriptorValue(value: any) {
|
||||
// Arrays
|
||||
if (objectType(value) === "[object Array]") {
|
||||
const array = [];
|
||||
for (let v of value) {
|
||||
v = cloneDescriptorValue(v);
|
||||
array.push(v);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// Objects
|
||||
if (objectType(value) === "[object Object]") {
|
||||
const obj = {};
|
||||
const props = Object.keys(value);
|
||||
for (const prop of props) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(value, prop);
|
||||
if (!descriptor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptor.value) {
|
||||
descriptor.value = cloneDescriptorValue(descriptor.value);
|
||||
}
|
||||
Object.defineProperty(obj, prop, descriptor);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Other Types of Objects
|
||||
if (objectType(value) === "[object Date]") {
|
||||
return new Date(value.getTime());
|
||||
}
|
||||
|
||||
if (objectType(value) === "[object Map]") {
|
||||
const map = new Map();
|
||||
for (const entry of value) {
|
||||
map.set(entry[0], cloneDescriptorValue(entry[1]));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
if (objectType(value) === "[object Set]") {
|
||||
const set = new Set();
|
||||
for (const entry of value.entries()) {
|
||||
set.add(cloneDescriptorValue(entry[0]));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
// Types we don't need to clone or cannot clone.
|
||||
// Examples:
|
||||
// - Primitives don't need to clone
|
||||
// - Functions cannot clone
|
||||
return value;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function _merge(output: Record<string, any>, input: Record<string, any>) {
|
||||
const props = Object.keys(input);
|
||||
|
||||
for (const prop of props) {
|
||||
// Prevents Prototype Pollution
|
||||
if (prop === "__proto__") continue;
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(input, prop);
|
||||
if (!descriptor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = descriptor.value;
|
||||
if (value) descriptor.value = cloneDescriptorValue(value);
|
||||
|
||||
// If don't have prop => Define property
|
||||
// [ken@goauthentik] Using `hasOwn` is preferable over
|
||||
// the basic identity test, according to Typescript.
|
||||
if (!Object.hasOwn(output, prop)) {
|
||||
Object.defineProperty(output, prop, descriptor);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If have prop, but type is not object => Overwrite by redefining property
|
||||
if (typeof output[prop] !== "object") {
|
||||
Object.defineProperty(output, prop, descriptor);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If have prop, but type is Object => Concat the arrays together.
|
||||
if (objectType(descriptor.value) === "[object Array]") {
|
||||
output[prop] = output[prop].concat(descriptor.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If have prop, but type is Object => Merge.
|
||||
_merge(output[prop], descriptor.value);
|
||||
}
|
||||
}
|
||||
|
||||
export function merge(...sources: Array<object>) {
|
||||
const result = {};
|
||||
for (const source of sources) {
|
||||
_merge(result, source);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export default merge;
|
|
@ -54,6 +54,13 @@ export function camelToSnake(key: string): string {
|
|||
return result.split(" ").join("_").toLowerCase();
|
||||
}
|
||||
|
||||
const capitalize = (key: string) => (key.length === 0 ? "" : key[0].toUpperCase() + key.slice(1));
|
||||
|
||||
export function snakeToCamel(key: string) {
|
||||
const [start, ...rest] = key.split("_");
|
||||
return [start, ...rest.map(capitalize)].join("");
|
||||
}
|
||||
|
||||
export function groupBy<T>(objects: T[], callback: (obj: T) => string): Array<[string, T[]]> {
|
||||
const m = new Map<string, T[]>();
|
||||
objects.forEach((obj) => {
|
||||
|
|
72
web/src/components/HorizontalLightComponent.ts
Normal file
72
web/src/components/HorizontalLightComponent.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { TemplateResult, html, nothing } from "lit";
|
||||
import { property } from "lit/decorators.js";
|
||||
|
||||
type HelpType = TemplateResult | typeof nothing;
|
||||
|
||||
export class HorizontalLightComponent extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
// we're not actually using that and, for the meantime, we need the form handlers to be able to
|
||||
// find the children of this component.
|
||||
//
|
||||
// TODO: This abstraction is wrong; it's putting *more* layers in as a way of managing the
|
||||
// visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
|
||||
// general.
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
@property({ type: Object })
|
||||
bighelp?: TemplateResult | TemplateResult[];
|
||||
|
||||
@property({ type: Boolean })
|
||||
hidden = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
invalid = false;
|
||||
|
||||
@property({ attribute: false })
|
||||
errorMessages: string[] = [];
|
||||
|
||||
renderControl() {
|
||||
throw new Error("Must be implemented in a subclass");
|
||||
}
|
||||
|
||||
renderHelp(): HelpType[] {
|
||||
const bigHelp: HelpType[] = Array.isArray(this.bighelp)
|
||||
? this.bighelp
|
||||
: [this.bighelp ?? nothing];
|
||||
return [
|
||||
this.help ? html`<p class="pf-c-form__helper-text">${this.help}</p>` : nothing,
|
||||
...bigHelp,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
// prettier-ignore
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
?required=${this.required}
|
||||
?hidden=${this.hidden}
|
||||
name=${this.name}
|
||||
.errorMessages=${this.errorMessages}
|
||||
?invalid=${this.invalid}
|
||||
>
|
||||
${this.renderControl()}
|
||||
${this.renderHelp()}
|
||||
</ak-form-element-horizontal> `;
|
||||
}
|
||||
}
|
150
web/src/components/ak-multi-select.ts
Normal file
150
web/src/components/ak-multi-select.ts
Normal file
|
@ -0,0 +1,150 @@
|
|||
import "@goauthentik/app/elements/forms/HorizontalFormElement";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { TemplateResult, css, 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 { Ref, createRef, ref } from "lit/directives/ref.js";
|
||||
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
type Pair = [string, string];
|
||||
|
||||
const selectStyles = css`
|
||||
select[multiple] {
|
||||
min-height: 15rem;
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* Horizontal layout control with a multi-select.
|
||||
*
|
||||
* @part select - The select itself, to override the height specified above.
|
||||
*/
|
||||
@customElement("ak-multi-select")
|
||||
export class AkMultiSelect extends AKElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.dataset.akControl = "true";
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [PFBase, PFForm, PFFormControl, selectStyles];
|
||||
}
|
||||
|
||||
/**
|
||||
* The [name] attribute, which is also distributed to the layout manager and the input control.
|
||||
*/
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
/**
|
||||
* The text label to display on the control
|
||||
*/
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
/**
|
||||
* The values to be displayed in the select. The format is [Value, Label], where the label is
|
||||
* what will be displayed.
|
||||
*/
|
||||
@property({ attribute: false })
|
||||
options: Pair[] = [];
|
||||
|
||||
/**
|
||||
* If true, at least one object must be selected
|
||||
*/
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
/**
|
||||
* Supporting a simple help string
|
||||
*/
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
/**
|
||||
* For more complex help instructions, provide a template result.
|
||||
*/
|
||||
@property({ type: Object })
|
||||
bighelp!: TemplateResult | TemplateResult[];
|
||||
|
||||
/**
|
||||
* An array of strings representing the objects currently selected.
|
||||
*/
|
||||
@property({ type: Array })
|
||||
values: string[] = [];
|
||||
|
||||
/**
|
||||
* Helper accessor for older code
|
||||
*/
|
||||
get value() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
/**
|
||||
* One of two criteria (the other being the data-ak-control flag) that specifies this as a
|
||||
* control that produces values of specific interest to our REST API. This is our modern
|
||||
* accessor name.
|
||||
*/
|
||||
json() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
renderHelp() {
|
||||
return [
|
||||
this.help ? html`<p class="pf-c-form__helper-text">${this.help}</p>` : nothing,
|
||||
this.bighelp ? this.bighelp : nothing,
|
||||
];
|
||||
}
|
||||
|
||||
handleChange(ev: Event) {
|
||||
if (ev.type === "change") {
|
||||
this.values = Array.from(this.selectRef.value!.querySelectorAll("option"))
|
||||
.filter((option) => option.selected)
|
||||
.map((option) => option.value);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("ak-select", {
|
||||
detail: this.values,
|
||||
composed: true,
|
||||
bubbles: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
selectRef: Ref<HTMLSelectElement> = createRef();
|
||||
|
||||
render() {
|
||||
return html` <div class="pf-c-form">
|
||||
<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
?required=${this.required}
|
||||
name=${this.name}
|
||||
>
|
||||
<select
|
||||
part="select"
|
||||
class="pf-c-form-control"
|
||||
name=${ifDefined(this.name)}
|
||||
multiple
|
||||
${ref(this.selectRef)}
|
||||
@change=${this.handleChange}
|
||||
>
|
||||
${map(
|
||||
this.options,
|
||||
([value, label]) =>
|
||||
html`<option value=${value} ?selected=${this.values.includes(value)}>
|
||||
${label}
|
||||
</option>`,
|
||||
)}
|
||||
</select>
|
||||
${this.renderHelp()}
|
||||
</ak-form-element-horizontal>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default AkMultiSelect;
|
|
@ -1,51 +1,21 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { HorizontalLightComponent } from "./HorizontalLightComponent";
|
||||
|
||||
@customElement("ak-number-input")
|
||||
export class AkNumberInput extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
// we're not actually using that and, for the meantime, we need the form handlers to be able to
|
||||
// find the children of this component.
|
||||
//
|
||||
// TODO: This abstraction is wrong; it's putting *more* layers in as a way of managing the
|
||||
// visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
|
||||
// general.
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
export class AkNumberInput extends HorizontalLightComponent {
|
||||
@property({ type: Number, reflect: true })
|
||||
value = 0;
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
render() {
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
?required=${this.required}
|
||||
name=${this.name}
|
||||
>
|
||||
<input
|
||||
renderControl() {
|
||||
return html`<input
|
||||
type="number"
|
||||
value=${ifDefined(this.value)}
|
||||
class="pf-c-form-control"
|
||||
?required=${this.required}
|
||||
/>
|
||||
${this.help ? html`<p class="pf-c-form__helper-text">${this.help}</p>` : nothing}
|
||||
</ak-form-element-horizontal> `;
|
||||
/>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,13 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { RadioOption } from "@goauthentik/elements/forms/Radio";
|
||||
import "@goauthentik/elements/forms/Radio";
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import { HorizontalLightComponent } from "./HorizontalLightComponent";
|
||||
|
||||
@customElement("ak-radio-input")
|
||||
export class AkRadioInput<T> extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
// we're not actually using that and, for the meantime, we need the form handlers to be able to
|
||||
// find the children of this component.
|
||||
//
|
||||
// TODO: This abstraction is wrong; it's putting *more* layers in as a way of managing the
|
||||
// visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
|
||||
// general.
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
export class AkRadioInput<T> extends HorizontalLightComponent {
|
||||
@property({ type: Object })
|
||||
value!: T;
|
||||
|
||||
|
@ -37,24 +15,25 @@ export class AkRadioInput<T> extends AKElement {
|
|||
options: RadioOption<T>[] = [];
|
||||
|
||||
handleInput(ev: CustomEvent) {
|
||||
if ("detail" in ev) {
|
||||
this.value = ev.detail.value;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
?required=${this.required}
|
||||
name=${this.name}
|
||||
>
|
||||
<ak-radio
|
||||
renderHelp() {
|
||||
// This is weird, but Typescript says it's necessary?
|
||||
return [nothing as typeof nothing];
|
||||
}
|
||||
|
||||
renderControl() {
|
||||
return html`<ak-radio
|
||||
.options=${this.options}
|
||||
.value=${this.value}
|
||||
@input=${this.handleInput}
|
||||
></ak-radio>
|
||||
${this.help.trim()
|
||||
? html`<p class="pf-c-form__helper-radio">${this.help}</p>`
|
||||
: nothing}
|
||||
</ak-form-element-horizontal> `;
|
||||
: nothing}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,44 +1,16 @@
|
|||
import { convertToSlug } from "@goauthentik/common/utils";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { TemplateResult, html, nothing } from "lit";
|
||||
import { html } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { HorizontalLightComponent } from "./HorizontalLightComponent";
|
||||
|
||||
@customElement("ak-slug-input")
|
||||
export class AkSlugInput extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
// we're not actually using that and, for the meantime, we need the form handlers to be able to
|
||||
// find the children of this component.
|
||||
//
|
||||
// TODO: This abstraction is wrong; it's putting *more* layers in as a way of managing the
|
||||
// visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
|
||||
// general.
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
export class AkSlugInput extends HorizontalLightComponent {
|
||||
@property({ type: String, reflect: true })
|
||||
value = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
hidden = false;
|
||||
|
||||
@property({ type: Object })
|
||||
bighelp!: TemplateResult | TemplateResult[];
|
||||
|
||||
@property({ type: String })
|
||||
source = "";
|
||||
|
||||
|
@ -59,13 +31,6 @@ export class AkSlugInput extends AKElement {
|
|||
this.input.addEventListener("input", this.handleTouch);
|
||||
}
|
||||
|
||||
renderHelp() {
|
||||
return [
|
||||
this.help ? html`<p class="pf-c-form__helper-text">${this.help}</p>` : nothing,
|
||||
this.bighelp ? this.bighelp : nothing,
|
||||
];
|
||||
}
|
||||
|
||||
// Do not stop propagation of this event; it must be sent up the tree so that a parent
|
||||
// component, such as a custom forms manager, may receive it.
|
||||
handleTouch(ev: Event) {
|
||||
|
@ -150,21 +115,13 @@ export class AkSlugInput extends AKElement {
|
|||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
?required=${this.required}
|
||||
?hidden=${this.hidden}
|
||||
name=${this.name}
|
||||
>
|
||||
<input
|
||||
renderControl() {
|
||||
return html`<input
|
||||
type="text"
|
||||
value=${ifDefined(this.value)}
|
||||
class="pf-c-form-control"
|
||||
?required=${this.required}
|
||||
/>
|
||||
${this.renderHelp()}
|
||||
</ak-form-element-horizontal> `;
|
||||
/>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,65 +1,21 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { TemplateResult, html, nothing } from "lit";
|
||||
import { html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { HorizontalLightComponent } from "./HorizontalLightComponent";
|
||||
|
||||
@customElement("ak-text-input")
|
||||
export class AkTextInput extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
// we're not actually using that and, for the meantime, we need the form handlers to be able to
|
||||
// find the children of this component.
|
||||
//
|
||||
// TODO: This abstraction is wrong; it's putting *more* layers in as a way of managing the
|
||||
// visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
|
||||
// general.
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
export class AkTextInput extends HorizontalLightComponent {
|
||||
@property({ type: String, reflect: true })
|
||||
value = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
hidden = false;
|
||||
|
||||
@property({ type: Object })
|
||||
bighelp!: TemplateResult | TemplateResult[];
|
||||
|
||||
renderHelp() {
|
||||
return [
|
||||
this.help ? html`<p class="pf-c-form__helper-text">${this.help}</p>` : nothing,
|
||||
this.bighelp ? this.bighelp : nothing,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
?required=${this.required}
|
||||
?hidden=${this.hidden}
|
||||
name=${this.name}
|
||||
>
|
||||
<input
|
||||
renderControl() {
|
||||
return html` <input
|
||||
type="text"
|
||||
value=${ifDefined(this.value)}
|
||||
class="pf-c-form-control"
|
||||
?required=${this.required}
|
||||
/>
|
||||
${this.renderHelp()}
|
||||
</ak-form-element-horizontal> `;
|
||||
/>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,57 +1,22 @@
|
|||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { TemplateResult, html, nothing } from "lit";
|
||||
import { html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import { HorizontalLightComponent } from "./HorizontalLightComponent";
|
||||
|
||||
@customElement("ak-textarea-input")
|
||||
export class AkTextareaInput extends AKElement {
|
||||
// Render into the lightDOM. This effectively erases the shadowDOM nature of this component, but
|
||||
// we're not actually using that and, for the meantime, we need the form handlers to be able to
|
||||
// find the children of this component.
|
||||
//
|
||||
// TODO: This abstraction is wrong; it's putting *more* layers in as a way of managing the
|
||||
// visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
|
||||
// general.
|
||||
protected createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
name!: string;
|
||||
|
||||
@property({ type: String })
|
||||
label = "";
|
||||
|
||||
@property({ type: String })
|
||||
export class AkTextareaInput extends HorizontalLightComponent {
|
||||
@property({ type: String, reflect: true })
|
||||
value = "";
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@property({ type: String })
|
||||
help = "";
|
||||
|
||||
@property({ type: Object })
|
||||
bighelp!: TemplateResult | TemplateResult[];
|
||||
|
||||
renderHelp() {
|
||||
return [
|
||||
this.help ? html`<p class="pf-c-form__helper-textarea">${this.help}</p>` : nothing,
|
||||
this.bighelp ? this.bighelp : nothing,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${this.label}
|
||||
renderControl() {
|
||||
// Prevent the leading spaces added by Prettier's whitespace algo
|
||||
// prettier-ignore
|
||||
return html`<textarea
|
||||
class="pf-c-form-control"
|
||||
?required=${this.required}
|
||||
name=${this.name}
|
||||
>
|
||||
<textarea class="pf-c-form-control" ?required=${this.required} name=${this.name}>
|
||||
${this.value !== undefined ? this.value : ""}</textarea
|
||||
>
|
||||
${this.renderHelp()}
|
||||
</ak-form-element-horizontal> `;
|
||||
>${this.value !== undefined ? this.value : ""}</textarea
|
||||
> `;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
79
web/src/components/stories/ak-multi-select.stories.ts
Normal file
79
web/src/components/stories/ak-multi-select.stories.ts
Normal file
|
@ -0,0 +1,79 @@
|
|||
import "@goauthentik/elements/messages/MessageContainer";
|
||||
import { Meta } from "@storybook/web-components";
|
||||
|
||||
import { TemplateResult, html, render } from "lit";
|
||||
|
||||
import "../ak-multi-select";
|
||||
import AkMultiSelect from "../ak-multi-select";
|
||||
|
||||
const metadata: Meta<AkMultiSelect> = {
|
||||
title: "Components / MultiSelect",
|
||||
component: "ak-multi-select",
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "A stylized value control for multi-select displays",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default metadata;
|
||||
|
||||
const container = (testItem: TemplateResult) =>
|
||||
html` <div style="background: #fff; padding: 2em">
|
||||
<style>
|
||||
li {
|
||||
display: block;
|
||||
}
|
||||
p {
|
||||
margin-top: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
${testItem}
|
||||
|
||||
<div id="message-pad" style="margin-top: 1em"></div>
|
||||
</div>`;
|
||||
|
||||
const testOptions = [
|
||||
["funky", "Option One: Funky"],
|
||||
["strange", "Option Two: Strange"],
|
||||
["weird", "Option Three: Weird"],
|
||||
];
|
||||
|
||||
export const RadioInput = () => {
|
||||
const result = "";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const displayChange = (ev: any) => {
|
||||
const messagePad = document.getElementById("message-pad");
|
||||
const component: AkMultiSelect | null = document.querySelector(
|
||||
'ak-multi-select[name="ak-test-multi-select"]',
|
||||
);
|
||||
|
||||
const results = html`
|
||||
<p>Results from event:</p>
|
||||
<ul style="list-style-type: disc">
|
||||
${ev.target.value.map((v: string) => html`<li>${v}</li>`)}
|
||||
</ul>
|
||||
<p>Results from component:</p>
|
||||
<ul style="list-style-type: disc">
|
||||
${component!.json().map((v: string) => html`<li>${v}</li>`)}
|
||||
</ul>
|
||||
`;
|
||||
|
||||
render(results, messagePad!);
|
||||
};
|
||||
|
||||
return container(
|
||||
html`<ak-multi-select
|
||||
@ak-select=${displayChange}
|
||||
label="Test Radio Button"
|
||||
name="ak-test-multi-select"
|
||||
help="This is where you would read the help messages"
|
||||
.options=${testOptions}
|
||||
></ak-multi-select>
|
||||
<div>${result}</div>`,
|
||||
);
|
||||
};
|
|
@ -31,10 +31,15 @@ export interface KeyUnknown {
|
|||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
// Literally the only field `assignValue()` cares about.
|
||||
type HTMLNamedElement = Pick<HTMLInputElement, "name">;
|
||||
|
||||
type AkControlElement = HTMLInputElement & { json: () => string | string[] };
|
||||
|
||||
/**
|
||||
* Recursively assign `value` into `json` while interpreting the dot-path of `element.name`
|
||||
*/
|
||||
function assignValue(element: HTMLInputElement, value: unknown, json: KeyUnknown): void {
|
||||
function assignValue(element: HTMLNamedElement, value: unknown, json: KeyUnknown): void {
|
||||
let parent = json;
|
||||
if (!element.name?.includes(".")) {
|
||||
parent[element.name] = value;
|
||||
|
@ -60,6 +65,16 @@ export function serializeForm<T extends KeyUnknown>(
|
|||
const json: { [key: string]: unknown } = {};
|
||||
elements.forEach((element) => {
|
||||
element.requestUpdate();
|
||||
if (element.hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Tighten up the typing so that we can handle both.
|
||||
if ("akControl" in element.dataset) {
|
||||
assignValue(element, (element as unknown as AkControlElement).json(), json);
|
||||
return;
|
||||
}
|
||||
|
||||
const inputElement = element.querySelector<HTMLInputElement>("[name]");
|
||||
if (element.hidden || !inputElement) {
|
||||
return;
|
||||
|
|
|
@ -5800,12 +5800,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s848288f8c2265aad">
|
||||
<source>Your application has been saved</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
</trans-unit>
|
||||
|
@ -6075,6 +6069,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -6077,12 +6077,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s848288f8c2265aad">
|
||||
<source>Your application has been saved</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
</trans-unit>
|
||||
|
@ -6352,6 +6346,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -5716,12 +5716,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s848288f8c2265aad">
|
||||
<source>Your application has been saved</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
</trans-unit>
|
||||
|
@ -5991,6 +5985,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -7617,14 +7617,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
|||
<source>Your application has been saved</source>
|
||||
<target>L'application a été sauvegardée</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
<target>Dans l'application :</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
<target>Dans le fournisseur :</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
<target>Nom d'affichage de la méthode.</target>
|
||||
|
@ -7986,6 +7978,54 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
|||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
<target>Lorsqu'activé, l'étape acceptera toujours l'identifiant utilisateur donné et continuera.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -5924,12 +5924,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s848288f8c2265aad">
|
||||
<source>Your application has been saved</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
</trans-unit>
|
||||
|
@ -6199,6 +6193,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -7556,14 +7556,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<source>Your application has been saved</source>
|
||||
<target>Ŷōũŕ àƥƥĺĩćàţĩōń ĥàś ƀēēń śàvēď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
<target>Ĩń ţĥē Àƥƥĺĩćàţĩōń:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
<target>Ĩń ţĥē Ƥŕōvĩďēŕ:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
<target>Mēţĥōď'ś ďĩśƥĺàŷ Ńàmē.</target>
|
||||
|
@ -7732,149 +7724,261 @@ 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>Ēxţēŕńàĺ àƥƥĺĩćàţĩōńś ţĥàţ ũśē àũţĥēńţĩķ àś àń ĩďēńţĩţŷ ƥŕōvĩďēŕ vĩà ƥŕōţōćōĺś ĺĩķē ŌÀũţĥ2 àńď ŚÀMĹ. Àĺĺ àƥƥĺĩćàţĩōńś àŕē śĥōŵń ĥēŕē, ēvēń ōńēś ŷōũ ćàńńōţ àććēśś.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1cc306d8e28c4464">
|
||||
<source>Deny message</source>
|
||||
<target>Ďēńŷ mēśśàĝē</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6985c401e1100122">
|
||||
<source>Message shown when this stage is run.</source>
|
||||
<target>Mēśśàĝē śĥōŵń ŵĥēń ţĥĩś śţàĝē ĩś ŕũń.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s09f0c100d0ad2fec">
|
||||
<source>Open Wizard</source>
|
||||
<target>Ōƥēń Ŵĩźàŕď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf2ef885f7d0a101d">
|
||||
<source>Demo Wizard</source>
|
||||
<target>Ďēmō Ŵĩźàŕď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s77505ee5d2e45e53">
|
||||
<source>Run the demo wizard</source>
|
||||
<target>Ŕũń ţĥē ďēmō ŵĩźàŕď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4498e890d47a8066">
|
||||
<source>OAuth2/OIDC (Open Authorization/OpenID Connect)</source>
|
||||
<target>ŌÀũţĥ2/ŌĨĎĆ (Ōƥēń Àũţĥōŕĩźàţĩōń/ŌƥēńĨĎ Ćōńńēćţ)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4f2e195d09e2868c">
|
||||
<source>LDAP (Lightweight Directory Access Protocol)</source>
|
||||
<target>ĹĎÀƤ (Ĺĩĝĥţŵēĩĝĥţ Ďĩŕēćţōŕŷ Àććēśś Ƥŕōţōćōĺ)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7f5bb0c9923315ed">
|
||||
<source>Forward Auth (Single Application)</source>
|
||||
<target>Ƒōŕŵàŕď Àũţĥ (Śĩńĝĺē Àƥƥĺĩćàţĩōń)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf8008d2d6b064b95">
|
||||
<source>Forward Auth (Domain Level)</source>
|
||||
<target>Ƒōŕŵàŕď Àũţĥ (Ďōmàĩń Ĺēvēĺ)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfa8a1ffa9fee07d3">
|
||||
<source>SAML (Security Assertion Markup Language)</source>
|
||||
<target>ŚÀMĹ (Śēćũŕĩţŷ Àśśēŕţĩōń Màŕķũƥ Ĺàńĝũàĝē)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s848a23972e388662">
|
||||
<source>RADIUS (Remote Authentication Dial-In User Service)</source>
|
||||
<target>ŔÀĎĨŨŚ (Ŕēmōţē Àũţĥēńţĩćàţĩōń Ďĩàĺ-Ĩń Ũśēŕ Śēŕvĩćē)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3e902999ddf7b50e">
|
||||
<source>SCIM (System for Cross-domain Identity Management)</source>
|
||||
<target>ŚĆĨM (Śŷśţēm ƒōŕ Ćŕōśś-ďōmàĩń Ĩďēńţĩţŷ Màńàĝēmēńţ)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdc5690be4a342985">
|
||||
<source>The token has been copied to your clipboard</source>
|
||||
<target>Ţĥē ţōķēń ĥàś ƀēēń ćōƥĩēď ţō ŷōũŕ ćĺĩƥƀōàŕď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7f3edfee24690c9f">
|
||||
<source>The token was displayed because authentik does not have permission to write to the clipboard</source>
|
||||
<target>Ţĥē ţōķēń ŵàś ďĩśƥĺàŷēď ƀēćàũśē àũţĥēńţĩķ ďōēś ńōţ ĥàvē ƥēŕmĩśśĩōń ţō ŵŕĩţē ţō ţĥē ćĺĩƥƀōàŕď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="saf6097bfa25205b8">
|
||||
<source>A copy of this recovery link has been placed in your clipboard</source>
|
||||
<target>À ćōƥŷ ōƒ ţĥĩś ŕēćōvēŕŷ ĺĩńķ ĥàś ƀēēń ƥĺàćēď ĩń ŷōũŕ ćĺĩƥƀōàŕď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5b8ee296ed258568">
|
||||
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
|
||||
<target>Ţĥē ćũŕŕēńţ ţēńàńţ mũśţ ĥàvē à ŕēćōvēŕŷ ƒĺōŵ ćōńƒĩĝũŕēď ţō ũśē à ŕēćōvēŕŷ ĺĩńķ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s895514dda9cb9c94">
|
||||
<source>Create recovery link</source>
|
||||
<target>Ćŕēàţē ŕēćōvēŕŷ ĺĩńķ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="se5c795faf2c07514">
|
||||
<source>Create Recovery Link</source>
|
||||
<target>Ćŕēàţē Ŕēćōvēŕŷ Ĺĩńķ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s84fcddede27b8e2a">
|
||||
<source>External</source>
|
||||
<target>Ēxţēŕńàĺ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a635369edaf4dc3">
|
||||
<source>Service account</source>
|
||||
<target>Śēŕvĩćē àććōũńţ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sff930bf2834e2201">
|
||||
<source>Service account (internal)</source>
|
||||
<target>Śēŕvĩćē àććōũńţ (ĩńţēŕńàĺ)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s66313b45b69cfc88">
|
||||
<source>Check the release notes</source>
|
||||
<target>Ćĥēćķ ţĥē ŕēĺēàśē ńōţēś</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4d7bae2440d9781">
|
||||
<source>User Statistics</source>
|
||||
<target>Ũśēŕ Śţàţĩśţĩćś</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0924f51b028233a3">
|
||||
<source><No name set></source>
|
||||
<target><Ńō ńàmē śēţ></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdc9a6ad1af30572c">
|
||||
<source>For nginx's auth_request or traefik's forwardAuth</source>
|
||||
<target>Ƒōŕ ńĝĩńx'ś àũţĥ_ŕēǫũēśţ ōŕ ţŕàēƒĩķ'ś ƒōŕŵàŕďÀũţĥ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfc31264ef7ff86ef">
|
||||
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
|
||||
<target>Ƒōŕ ńĝĩńx'ś àũţĥ_ŕēǫũēśţ ōŕ ţŕàēƒĩķ'ś ƒōŕŵàŕďÀũţĥ ƥēŕ ŕōōţ ďōmàĩń</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc615309d10a9228c">
|
||||
<source>RBAC is in preview.</source>
|
||||
<target>ŔßÀĆ ĩś ĩń ƥŕēvĩēŵ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s32babfed740fd3c1">
|
||||
<source>User type used for newly created users.</source>
|
||||
<target>Ũśēŕ ţŷƥē ũśēď ƒōŕ ńēŵĺŷ ćŕēàţēď ũśēŕś.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a34a6be4c68ec87">
|
||||
<source>Users created</source>
|
||||
<target>Ũśēŕś ćŕēàţēď</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s275c956687e2e656">
|
||||
<source>Failed logins</source>
|
||||
<target>Ƒàĩĺēď ĺōĝĩńś</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb35c08e3a541188f">
|
||||
<source>Also known as Client ID.</source>
|
||||
<target>Àĺśō ķńōŵń àś Ćĺĩēńţ ĨĎ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd46fd9b647cfea10">
|
||||
<source>Also known as Client Secret.</source>
|
||||
<target>Àĺśō ķńōŵń àś Ćĺĩēńţ Śēćŕēţ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4476e9c50cfd13f4">
|
||||
<source>Global status</source>
|
||||
<target>Ĝĺōƀàĺ śţàţũś</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd21a971eea208533">
|
||||
<source>Vendor</source>
|
||||
<target>Vēńďōŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sadadfe9dfa06d7dd">
|
||||
<source>No sync status.</source>
|
||||
<target>Ńō śŷńć śţàţũś.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2b1c81130a65a55b">
|
||||
<source>Sync currently running.</source>
|
||||
<target>Śŷńć ćũŕŕēńţĺŷ ŕũńńĩńĝ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf36170f71cea38c2">
|
||||
<source>Connectivity</source>
|
||||
<target>Ćōńńēćţĩvĩţŷ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd94e99af8b41ff54">
|
||||
<source>0: Too guessable: risky password. (guesses &lt; 10^3)</source>
|
||||
<target>0: Ţōō ĝũēśśàƀĺē: ŕĩśķŷ ƥàśśŵōŕď. (ĝũēśśēś &ĺţ; 10^3)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc926385d1a624c3a">
|
||||
<source>1: Very guessable: protection from throttled online attacks. (guesses &lt; 10^6)</source>
|
||||
<target>1: Vēŕŷ ĝũēśśàƀĺē: ƥŕōţēćţĩōń ƒŕōm ţĥŕōţţĺēď ōńĺĩńē àţţàćķś. (ĝũēśśēś &ĺţ; 10^6)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s8aae61c41319602c">
|
||||
<source>2: Somewhat guessable: protection from unthrottled online attacks. (guesses &lt; 10^8)</source>
|
||||
<target>2: Śōmēŵĥàţ ĝũēśśàƀĺē: ƥŕōţēćţĩōń ƒŕōm ũńţĥŕōţţĺēď ōńĺĩńē àţţàćķś. (ĝũēśśēś &ĺţ; 10^8)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1f4b57e722a89d6">
|
||||
<source>3: Safely unguessable: moderate protection from offline slow-hash scenario. (guesses &lt; 10^10)</source>
|
||||
<target>3: Śàƒēĺŷ ũńĝũēśśàƀĺē: mōďēŕàţē ƥŕōţēćţĩōń ƒŕōm ōƒƒĺĩńē śĺōŵ-ĥàśĥ śćēńàŕĩō. (ĝũēśśēś &ĺţ; 10^10)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd47f3d3c9741343d">
|
||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||
<target>4: Vēŕŷ ũńĝũēśśàƀĺē: śţŕōńĝ ƥŕōţēćţĩōń ƒŕōm ōƒƒĺĩńē śĺōŵ-ĥàśĥ śćēńàŕĩō. (ĝũēśśēś &ĝţ;= 10^10)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3d2a8b86a4f5a810">
|
||||
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||
<target>Śũććēśśƒũĺĺŷ ćŕēàţēď ũśēŕ àńď àďďēď ţō ĝŕōũƥ <x id="0" equiv-text="${this.group.name}"/></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s824e0943a7104668">
|
||||
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
|
||||
<target>Ţĥĩś ũśēŕ ŵĩĺĺ ƀē àďďēď ţō ţĥē ĝŕōũƥ "<x id="0" equiv-text="${this.targetGroup.name}"/>".</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s62e7f6ed7d9cb3ca">
|
||||
<source>Pretend user exists</source>
|
||||
<target>Ƥŕēţēńď ũśēŕ ēxĩśţś</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
<target>Ŵĥēń ēńàƀĺēď, ţĥē śţàĝē ŵĩĺĺ àĺŵàŷś àććēƥţ ţĥē ĝĩvēń ũśēŕ ĩďēńţĩƒĩēŕ àńď ćōńţĩńũē.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
<target>Ţĥēŕē ŵàś àń ēŕŕōŕ ĩń ţĥē àƥƥĺĩćàţĩōń.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
<target>Ŕēvĩēŵ ţĥē àƥƥĺĩćàţĩōń.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
<target>Ţĥēŕē ŵàś àń ēŕŕōŕ ĩń ţĥē ƥŕōvĩďēŕ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
<target>Ŕēvĩēŵ ţĥē ƥŕōvĩďēŕ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
<target>Ţĥēŕē ŵàś àń ēŕŕōŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
<target>Ţĥēŕē ŵàś àń ēŕŕōŕ ćŕēàţĩńĝ ţĥē àƥƥĺĩćàţĩōń, ƀũţ ńō ēŕŕōŕ mēśśàĝē ŵàś śēńţ. Ƥĺēàśē ŕēvĩēŵ ţĥē śēŕvēŕ ĺōĝś.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
<target>Ćōńƒĩĝũŕē ĹĎÀƤ Ƥŕōvĩďēŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
<target>Ćōńƒĩĝũŕē ŌÀũţĥ2/ŌƥēńĨď Ƥŕōvĩďēŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
<target>Ćōńƒĩĝũŕē Ƥŕōxŷ Ƥŕōvĩďēŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
<target>ÀďďĩţĩōńàĺŚćōƥēś</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
<target>Ćōńƒĩĝũŕē Ŕàďĩũś Ƥŕōvĩďēŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
<target>Ćōńƒĩĝũŕē ŚÀMĹ Ƥŕōvĩďēŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
<target>Ƥŕōƥēŕţŷ màƥƥĩńĝś ũśēď ƒōŕ ũśēŕ màƥƥĩńĝ.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
<target>Ćōńƒĩĝũŕē ŚĆĨM Ƥŕōvĩďēŕ</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
<target>Ƥŕōƥēŕţŷ màƥƥĩńĝś ũśēď ƒōŕ ĝŕōũƥ ćŕēàţĩōń.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body></file></xliff>
|
||||
|
|
|
@ -5709,12 +5709,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s848288f8c2265aad">
|
||||
<source>Your application has been saved</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
</trans-unit>
|
||||
|
@ -5984,6 +5978,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -7619,14 +7619,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<source>Your application has been saved</source>
|
||||
<target>您的应用程序已保存</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
<target>在应用程序中:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
<target>在提供程序中:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
<target>方法的显示名称。</target>
|
||||
|
@ -7988,6 +7980,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
<target>启用时,此阶段总是会接受指定的用户 ID 并继续。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -5757,12 +5757,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<trans-unit id="s848288f8c2265aad">
|
||||
<source>Your application has been saved</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
</trans-unit>
|
||||
|
@ -6032,6 +6026,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s52bdc80690a9a8dc">
|
||||
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -7555,14 +7555,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
<source>Your application has been saved</source>
|
||||
<target>已經儲存您的應用程式</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf60f1e5b76897c93">
|
||||
<source>In the Application:</source>
|
||||
<target>在應用程式:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ce65cf482b7bff0">
|
||||
<source>In the Provider:</source>
|
||||
<target>在供應商:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s67d858051b34c38b">
|
||||
<source>Method's display Name.</source>
|
||||
<target>方法的顯示名稱。</target>
|
||||
|
@ -7925,6 +7917,54 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||
</trans-unit>
|
||||
<trans-unit id="s5d7748b1d2363478">
|
||||
<source>Are you sure you want to remove the selected users from the group <x id="0" equiv-text="${this.targetGroup?.name}"/>?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="scda8dc24b561e205">
|
||||
<source>There was an error in the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdaca9c2c0361ed3a">
|
||||
<source>Review the application.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb50000a8fada5672">
|
||||
<source>There was an error in the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s21f95eaf151d4ce3">
|
||||
<source>Review the provider.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9fd39a5cb20b4e61">
|
||||
<source>There was an error</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7a6b3453209e1066">
|
||||
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1a711c19cda48375">
|
||||
<source>Configure LDAP Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9368e965b5c292ab">
|
||||
<source>Configure OAuth2/OpenId Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf5cbccdc6254c8dc">
|
||||
<source>Configure Proxy Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sf6d46bb442b77e91">
|
||||
<source>AdditionalScopes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s2c8c6f89089b31d4">
|
||||
<source>Configure Radius Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfe906cde5dddc041">
|
||||
<source>Configure SAML Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3defbacd01ad972">
|
||||
<source>Property mappings used for user mapping.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7ccce0ec8d228db6">
|
||||
<source>Configure SCIM Provider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd7728d2b6e1d25e9">
|
||||
<source>Property mappings used for group creation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7513372fe60f6387">
|
||||
<source>Event volume</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -5,7 +5,7 @@ title: Docker Compose installation
|
|||
This installation method is for test-setups and small-scale production setups.
|
||||
|
||||
:::info
|
||||
You can also [view a video walk-through](https://youtu.be/owk1a_1xYe4) of the installation process on Docker (with bonus details about email configuration and other important options).
|
||||
You can also [view a video walk-through](https://www.youtube.com/watch?v=O1qUbrk4Yc8) of the installation process on Docker (with bonus details about email configuration and other important options).
|
||||
:::
|
||||
|
||||
## Requirements
|
||||
|
|
|
@ -5,7 +5,7 @@ title: Kubernetes installation
|
|||
You can install authentik to run on Kubernetes using Helm Chart.
|
||||
|
||||
:::info
|
||||
You can also [view a video walk-through](https://youtu.be/owk1a_1xYe4) of the installation process on Kubernetes (with bonus details about email configuration and other important options).
|
||||
You can also [view a video walk-through](https://www.youtube.com/watch?v=O1qUbrk4Yc8) of the installation process on Kubernetes (with bonus details about email configuration and other important options).
|
||||
:::
|
||||
|
||||
### Requirements
|
||||
|
|
16
website/package-lock.json
generated
16
website/package-lock.json
generated
|
@ -26,14 +26,14 @@
|
|||
"react-dom": "^18.2.0",
|
||||
"react-feather": "^2.0.10",
|
||||
"react-toggle": "^4.1.3",
|
||||
"react-tooltip": "^5.24.0",
|
||||
"react-tooltip": "^5.25.0",
|
||||
"remark-github": "^12.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.0.1",
|
||||
"@docusaurus/tsconfig": "3.0.1",
|
||||
"@docusaurus/types": "3.0.1",
|
||||
"@types/react": "^18.2.41",
|
||||
"@types/react": "^18.2.42",
|
||||
"prettier": "3.1.0",
|
||||
"typescript": "~5.3.2"
|
||||
},
|
||||
|
@ -4373,9 +4373,9 @@
|
|||
"integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA=="
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.41",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.41.tgz",
|
||||
"integrity": "sha512-CwOGr/PiLiNBxEBqpJ7fO3kocP/2SSuC9fpH5K7tusrg4xPSRT/193rzolYwQnTN02We/ATXKnb6GqA5w4fRxw==",
|
||||
"version": "18.2.42",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.42.tgz",
|
||||
"integrity": "sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
|
@ -14365,9 +14365,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-tooltip": {
|
||||
"version": "5.24.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.24.0.tgz",
|
||||
"integrity": "sha512-HjstgpOrUwP4eN6mHU4EThpbxVuKO5SvqumRt1aAcPq0ya+pIVVxlwltndtdIIMBJ7w3jnN05vNfcfh2sxE2mQ==",
|
||||
"version": "5.25.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.25.0.tgz",
|
||||
"integrity": "sha512-/eGhmlwbHlJrVoUe75fb58rJfAy9aZnTvQAK9ZUPM0n9mmBGpEk13vDPiQVCeUuax+fBej+7JPsUXlhzaySc7w==",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"classnames": "^2.3.0"
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"react-dom": "^18.2.0",
|
||||
"react-feather": "^2.0.10",
|
||||
"react-toggle": "^4.1.3",
|
||||
"react-tooltip": "^5.24.0",
|
||||
"react-tooltip": "^5.25.0",
|
||||
"react": "^18.2.0",
|
||||
"remark-github": "^12.0.0"
|
||||
},
|
||||
|
@ -52,7 +52,7 @@
|
|||
"@docusaurus/module-type-aliases": "3.0.1",
|
||||
"@docusaurus/tsconfig": "3.0.1",
|
||||
"@docusaurus/types": "3.0.1",
|
||||
"@types/react": "^18.2.41",
|
||||
"@types/react": "^18.2.42",
|
||||
"prettier": "3.1.0",
|
||||
"typescript": "~5.3.2"
|
||||
},
|
||||
|
|
Reference in a new issue