Prep for monorepo use.
web: Update config. Flesh out build. Fix issue surrounding build. Fix paths. Update workspaces. Fix build steps. Apply linter. Temporarily remove problem rules. Add ignorefile. Prep for formatting. Lint website. Lint web, repo packages. Refine Prettier usage. Fix imports. Tidy build. Move node ignore files. Remove unused. Update job. Fix lint step. Build before compiling. Use root for paths. Fix issues surrounding import references, types, package names. Fix build paths. Tidy. Enforce prefix. Apply prefixes to imports. Enable linter, compiler, etc. Fix references. Update names. Mark optional. Revise mounts. Fix build order. Update package.json. Ignore all docusaurus. Fix paths, types. Clean up build steps, names. Fix paths. website: Fix nested paragraphs build warning. web: Enforce module resolution. Use consistent LTS version. Track Node version. Use default resolution. Test main entrypoint. Fix Node v20 compatibility. Add task names. WIP: Fix styles.
This commit is contained in:
@ -10,6 +10,9 @@ insert_final_newline = true
|
|||||||
[*.html]
|
[*.html]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[schemas/*.json]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
[*.{yaml,yml}]
|
[*.{yaml,yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
6
.github/actions/setup/action.yml
vendored
6
.github/actions/setup/action.yml
vendored
@ -28,9 +28,9 @@ runs:
|
|||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: web/package.json
|
node-version-file: package.json
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
cache-dependency-path: web/package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
@ -44,7 +44,7 @@ runs:
|
|||||||
run: |
|
run: |
|
||||||
export PSQL_TAG=${{ inputs.postgresql_version }}
|
export PSQL_TAG=${{ inputs.postgresql_version }}
|
||||||
docker compose -f .github/actions/setup/docker-compose.yml up -d
|
docker compose -f .github/actions/setup/docker-compose.yml up -d
|
||||||
cd web && npm ci
|
npm ci
|
||||||
- name: Generate config
|
- name: Generate config
|
||||||
shell: uv run python {0}
|
shell: uv run python {0}
|
||||||
run: |
|
run: |
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Re-usable workflow for a single-architecture build
|
# Re-usable workflow for a single-architecture build
|
||||||
name: Single-arch Container build
|
name: "Single-arch Container build"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
@ -42,7 +42,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: docker/setup-qemu-action@v3.6.0
|
- uses: docker/setup-qemu-action@v3.6.0
|
||||||
- uses: docker/setup-buildx-action@v3
|
- uses: docker/setup-buildx-action@v3
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
@ -64,12 +64,12 @@ jobs:
|
|||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: make empty clients
|
- name: Make empty clients
|
||||||
if: ${{ inputs.release }}
|
if: ${{ inputs.release }}
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ./gen-ts-api
|
mkdir -p ./gen-ts-api
|
||||||
mkdir -p ./gen-go-api
|
mkdir -p ./gen-go-api
|
||||||
- name: generate ts client
|
- name: Generate TypeScript API Client
|
||||||
if: ${{ !inputs.release }}
|
if: ${{ !inputs.release }}
|
||||||
run: make gen-client-ts
|
run: make gen-client-ts
|
||||||
- name: Build Docker Image
|
- name: Build Docker Image
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Re-usable workflow for a multi-architecture build
|
# Re-usable workflow for a multi-architecture build
|
||||||
name: Multi-arch container build
|
name: "Multi-arch container build"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
@ -49,7 +49,7 @@ jobs:
|
|||||||
shouldPush: ${{ steps.ev.outputs.shouldPush }}
|
shouldPush: ${{ steps.ev.outputs.shouldPush }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
tag: ${{ fromJson(needs.get-tags.outputs.tags) }}
|
tag: ${{ fromJson(needs.get-tags.outputs.tags) }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
|
6
.github/workflows/api-py-publish.yml
vendored
6
.github/workflows/api-py-publish.yml
vendored
@ -1,4 +1,5 @@
|
|||||||
name: authentik-api-py-publish
|
name: "Python API Publish"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
@ -7,6 +8,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: "Build and Publish"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
@ -30,7 +32,7 @@ jobs:
|
|||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version-file: "pyproject.toml"
|
python-version-file: "pyproject.toml"
|
||||||
- name: Generate API Client
|
- name: Generate Python API Client
|
||||||
run: make gen-client-py
|
run: make gen-client-py
|
||||||
- name: Publish package
|
- name: Publish package
|
||||||
working-directory: gen-py-api/
|
working-directory: gen-py-api/
|
||||||
|
7
.github/workflows/api-ts-publish.yml
vendored
7
.github/workflows/api-ts-publish.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-api-ts-publish
|
name: "TypeScript API Publish"
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
@ -7,6 +7,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: "Build and Publish"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@ -20,9 +21,9 @@ jobs:
|
|||||||
token: ${{ steps.generate_token.outputs.token }}
|
token: ${{ steps.generate_token.outputs.token }}
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: web/package.json
|
node-version-file: package.json
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
- name: Generate API Client
|
- name: Generate TypeScript API Client
|
||||||
run: make gen-client-ts
|
run: make gen-client-ts
|
||||||
- name: Publish package
|
- name: Publish package
|
||||||
working-directory: gen-ts-api/
|
working-directory: gen-ts-api/
|
||||||
|
4
.github/workflows/ci-aws-cfn.yml
vendored
4
.github/workflows/ci-aws-cfn.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-ci-aws-cfn
|
name: "authentik CI AWS CloudFormation"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -18,6 +18,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-changes-applied:
|
check-changes-applied:
|
||||||
|
name: "Check changes applied"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -36,6 +37,7 @@ jobs:
|
|||||||
uv run make aws-cfn
|
uv run make aws-cfn
|
||||||
git diff --exit-code
|
git diff --exit-code
|
||||||
ci-aws-cfn-mark:
|
ci-aws-cfn-mark:
|
||||||
|
name: "CI AWS CloudFormation Mark"
|
||||||
if: always()
|
if: always()
|
||||||
needs:
|
needs:
|
||||||
- check-changes-applied
|
- check-changes-applied
|
||||||
|
3
.github/workflows/ci-main-daily.yml
vendored
3
.github/workflows/ci-main-daily.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-ci-main-daily
|
name: "authentik CI Main Daily"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@ -9,6 +9,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-container:
|
test-container:
|
||||||
|
name: "Test Container ${{ matrix.version }}"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
62
.github/workflows/ci-main.yml
vendored
62
.github/workflows/ci-main.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-ci-main
|
name: "authentik CI Main"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -19,6 +19,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
|
name: "Lint"
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@ -33,9 +34,10 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup authentik env
|
- name: Setup authentik env
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
- name: run job
|
- name: Run job ${{ matrix.job }}
|
||||||
run: uv run make ci-${{ matrix.job }}
|
run: uv run make ci-${{ matrix.job }}
|
||||||
test-migrations:
|
test-migrations:
|
||||||
|
name: "Test Migrations"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -44,6 +46,7 @@ jobs:
|
|||||||
- name: run migrations
|
- name: run migrations
|
||||||
run: uv run python -m lifecycle.migrate
|
run: uv run python -m lifecycle.migrate
|
||||||
test-make-seed:
|
test-make-seed:
|
||||||
|
name: "Test Make Seed"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- id: seed
|
- id: seed
|
||||||
@ -52,7 +55,7 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
seed: ${{ steps.seed.outputs.seed }}
|
seed: ${{ steps.seed.outputs.seed }}
|
||||||
test-migrations-from-stable:
|
test-migrations-from-stable:
|
||||||
name: test-migrations-from-stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
|
name: "Test Migrations From Stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
needs: test-make-seed
|
needs: test-make-seed
|
||||||
@ -67,7 +70,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: checkout stable
|
- name: Checkout Stable
|
||||||
run: |
|
run: |
|
||||||
# Copy current, latest config to local
|
# Copy current, latest config to local
|
||||||
# Temporarly comment the .github backup while migrating to uv
|
# Temporarly comment the .github backup while migrating to uv
|
||||||
@ -84,9 +87,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
postgresql_version: ${{ matrix.psql }}
|
postgresql_version: ${{ matrix.psql }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
- name: run migrations to stable
|
- name: Run migrations to stable
|
||||||
run: poetry run python -m lifecycle.migrate
|
run: poetry run python -m lifecycle.migrate
|
||||||
- name: checkout current code
|
- name: Checkout current code
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
git fetch
|
git fetch
|
||||||
@ -97,10 +100,10 @@ jobs:
|
|||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
with:
|
with:
|
||||||
postgresql_version: ${{ matrix.psql }}
|
postgresql_version: ${{ matrix.psql }}
|
||||||
- name: migrate to latest
|
- name: Migrate to latest
|
||||||
run: |
|
run: |
|
||||||
uv run python -m lifecycle.migrate
|
uv run python -m lifecycle.migrate
|
||||||
- name: run tests
|
- name: Run tests
|
||||||
env:
|
env:
|
||||||
# Test in the main database that we just migrated from the previous stable version
|
# Test in the main database that we just migrated from the previous stable version
|
||||||
AUTHENTIK_POSTGRESQL__TEST__NAME: authentik
|
AUTHENTIK_POSTGRESQL__TEST__NAME: authentik
|
||||||
@ -110,7 +113,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
uv run make ci-test
|
uv run make ci-test
|
||||||
test-unittest:
|
test-unittest:
|
||||||
name: test-unittest - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
|
name: "Unit tests - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
needs: test-make-seed
|
needs: test-make-seed
|
||||||
@ -146,6 +149,7 @@ jobs:
|
|||||||
file: unittest.xml
|
file: unittest.xml
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
test-integration:
|
test-integration:
|
||||||
|
name: "Integration tests"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
@ -154,7 +158,7 @@ jobs:
|
|||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
- name: Create k8s Kind Cluster
|
- name: Create k8s Kind Cluster
|
||||||
uses: helm/kind-action@v1.12.0
|
uses: helm/kind-action@v1.12.0
|
||||||
- name: run integration
|
- name: Run integration
|
||||||
run: |
|
run: |
|
||||||
uv run coverage run manage.py test tests/integration
|
uv run coverage run manage.py test tests/integration
|
||||||
uv run coverage xml
|
uv run coverage xml
|
||||||
@ -170,49 +174,50 @@ jobs:
|
|||||||
file: unittest.xml
|
file: unittest.xml
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
test-e2e:
|
test-e2e:
|
||||||
name: test-e2e (${{ matrix.job.name }})
|
name: "Test E2E (${{ matrix.job.name }})"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
job:
|
job:
|
||||||
- name: proxy
|
- name: Proxy Provider
|
||||||
glob: tests/e2e/test_provider_proxy*
|
glob: tests/e2e/test_provider_proxy*
|
||||||
- name: oauth
|
- name: OAuth2 Provider
|
||||||
glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth*
|
glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth*
|
||||||
- name: oauth-oidc
|
- name: OIDC Provider
|
||||||
glob: tests/e2e/test_provider_oidc*
|
glob: tests/e2e/test_provider_oidc*
|
||||||
- name: saml
|
- name: SAML Provider
|
||||||
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
|
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
|
||||||
- name: ldap
|
- name: LDAP Provider
|
||||||
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
|
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
|
||||||
- name: radius
|
- name: RADIUS Provider
|
||||||
glob: tests/e2e/test_provider_radius*
|
glob: tests/e2e/test_provider_radius*
|
||||||
- name: scim
|
- name: SCIM Source
|
||||||
glob: tests/e2e/test_source_scim*
|
glob: tests/e2e/test_source_scim*
|
||||||
- name: flows
|
- name: Flows
|
||||||
glob: tests/e2e/test_flows*
|
glob: tests/e2e/test_flows*
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup authentik env
|
- name: Setup authentik env
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
- name: Setup e2e env (chrome, etc)
|
- name: Setup E2E env (chrome, etc)
|
||||||
run: |
|
run: |
|
||||||
docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
|
docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
|
||||||
- id: cache-web
|
- id: cache-web
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: web/dist
|
path: web/dist
|
||||||
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**') }}
|
key: ${{ runner.os }}-web-${{ hashFiles('./package-lock.json', 'web/src/**') }}
|
||||||
- name: prepare web ui
|
- name: Prepare Web UI
|
||||||
if: steps.cache-web.outputs.cache-hit != 'true'
|
if: steps.cache-web.outputs.cache-hit != 'true'
|
||||||
working-directory: web
|
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
make -C .. gen-client-ts
|
make gen-client-ts
|
||||||
npm run build
|
npm run build -w @goauthentik/web
|
||||||
- name: run e2e
|
|
||||||
|
npm run typecheck
|
||||||
|
- name: Run E2E tests
|
||||||
run: |
|
run: |
|
||||||
uv run coverage run manage.py test ${{ matrix.job.glob }}
|
uv run coverage run manage.py test ${{ matrix.job.glob }}
|
||||||
uv run coverage xml
|
uv run coverage xml
|
||||||
@ -228,6 +233,7 @@ jobs:
|
|||||||
file: unittest.xml
|
file: unittest.xml
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
ci-core-mark:
|
ci-core-mark:
|
||||||
|
name: "CI Core Mark"
|
||||||
if: always()
|
if: always()
|
||||||
needs:
|
needs:
|
||||||
- lint
|
- lint
|
||||||
@ -242,6 +248,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
jobs: ${{ toJSON(needs) }}
|
jobs: ${{ toJSON(needs) }}
|
||||||
build:
|
build:
|
||||||
|
name: "Build"
|
||||||
permissions:
|
permissions:
|
||||||
# Needed to upload container images to ghcr.io
|
# Needed to upload container images to ghcr.io
|
||||||
packages: write
|
packages: write
|
||||||
@ -255,6 +262,7 @@ jobs:
|
|||||||
image_name: ghcr.io/goauthentik/dev-server
|
image_name: ghcr.io/goauthentik/dev-server
|
||||||
release: false
|
release: false
|
||||||
pr-comment:
|
pr-comment:
|
||||||
|
name: "PR Comment"
|
||||||
needs:
|
needs:
|
||||||
- build
|
- build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -267,7 +275,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
|
32
.github/workflows/ci-outpost.yml
vendored
32
.github/workflows/ci-outpost.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-ci-outpost
|
name: "authentik CI Outpost"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -14,6 +14,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint-golint:
|
lint-golint:
|
||||||
|
name: "Lint Go"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -26,7 +27,7 @@ jobs:
|
|||||||
mkdir -p web/dist
|
mkdir -p web/dist
|
||||||
mkdir -p website/help
|
mkdir -p website/help
|
||||||
touch web/dist/test website/help/test
|
touch web/dist/test website/help/test
|
||||||
- name: Generate API
|
- name: Generate Go API Client
|
||||||
run: make gen-client-go
|
run: make gen-client-go
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v7
|
uses: golangci/golangci-lint-action@v7
|
||||||
@ -35,6 +36,7 @@ jobs:
|
|||||||
args: --timeout 5000s --verbose
|
args: --timeout 5000s --verbose
|
||||||
skip-cache: true
|
skip-cache: true
|
||||||
test-unittest:
|
test-unittest:
|
||||||
|
name: "Unit Test Go"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -43,12 +45,13 @@ jobs:
|
|||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
- name: Setup authentik env
|
- name: Setup authentik env
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
- name: Generate API
|
- name: Generate Go API Client
|
||||||
run: make gen-client-go
|
run: make gen-client-go
|
||||||
- name: Go unittests
|
- name: Go unittests
|
||||||
run: |
|
run: |
|
||||||
go test -timeout 0 -v -race -coverprofile=coverage.out -covermode=atomic -cover ./...
|
go test -timeout 0 -v -race -coverprofile=coverage.out -covermode=atomic -cover ./...
|
||||||
ci-outpost-mark:
|
ci-outpost-mark:
|
||||||
|
name: "CI Outpost Mark"
|
||||||
if: always()
|
if: always()
|
||||||
needs:
|
needs:
|
||||||
- lint-golint
|
- lint-golint
|
||||||
@ -59,6 +62,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
jobs: ${{ toJSON(needs) }}
|
jobs: ${{ toJSON(needs) }}
|
||||||
build-container:
|
build-container:
|
||||||
|
name: "Build Container"
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
needs:
|
needs:
|
||||||
- ci-outpost-mark
|
- ci-outpost-mark
|
||||||
@ -85,7 +89,7 @@ jobs:
|
|||||||
uses: docker/setup-qemu-action@v3.6.0
|
uses: docker/setup-qemu-action@v3.6.0
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
@ -99,7 +103,7 @@ jobs:
|
|||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Generate API
|
- name: Generate Go API Client
|
||||||
run: make gen-client-go
|
run: make gen-client-go
|
||||||
- name: Build Docker Image
|
- name: Build Docker Image
|
||||||
id: push
|
id: push
|
||||||
@ -122,6 +126,7 @@ jobs:
|
|||||||
subject-digest: ${{ steps.push.outputs.digest }}
|
subject-digest: ${{ steps.push.outputs.digest }}
|
||||||
push-to-registry: true
|
push-to-registry: true
|
||||||
build-binary:
|
build-binary:
|
||||||
|
name: "Build Binary"
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
needs:
|
needs:
|
||||||
- ci-outpost-mark
|
- ci-outpost-mark
|
||||||
@ -140,21 +145,22 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: package.json
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: package-lock.json
|
||||||
|
- name: Install Node.js dependencies
|
||||||
|
run: npm ci
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
- uses: actions/setup-node@v4
|
- name: Generate Go API Client
|
||||||
with:
|
|
||||||
node-version-file: web/package.json
|
|
||||||
cache: "npm"
|
|
||||||
cache-dependency-path: web/package-lock.json
|
|
||||||
- name: Generate API
|
|
||||||
run: make gen-client-go
|
run: make gen-client-go
|
||||||
- name: Build web
|
- name: Build web
|
||||||
working-directory: web/
|
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
npm run build-proxy
|
npm run build-proxy -w @goauthentik/web
|
||||||
- name: Build outpost
|
- name: Build outpost
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
|
88
.github/workflows/ci-web.yml
vendored
88
.github/workflows/ci-web.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-ci-web
|
name: CI Web UI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -13,54 +13,50 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
name: Lint
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
command:
|
|
||||||
- lint
|
|
||||||
- lint:lockfile
|
|
||||||
- tsc
|
|
||||||
- prettier-check
|
|
||||||
project:
|
|
||||||
- web
|
|
||||||
include:
|
|
||||||
- command: tsc
|
|
||||||
project: web
|
|
||||||
- command: lit-analyse
|
|
||||||
project: web
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: ${{ matrix.project }}/package.json
|
|
||||||
cache: "npm"
|
|
||||||
cache-dependency-path: ${{ matrix.project }}/package-lock.json
|
|
||||||
- working-directory: ${{ matrix.project }}/
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
- name: Generate API
|
|
||||||
run: make gen-client-ts
|
|
||||||
- name: Lint
|
|
||||||
working-directory: ${{ matrix.project }}/
|
|
||||||
run: npm run ${{ matrix.command }}
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: web/package.json
|
node-version-file: package.json
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
cache-dependency-path: web/package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- working-directory: web/
|
- name: Install Node.js dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Generate API
|
- name: Generate TypeScript API
|
||||||
|
run: make gen-client-ts
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
npm run build -w @goauthentik/web
|
||||||
|
- name: Type check
|
||||||
|
run: |
|
||||||
|
npm run typecheck
|
||||||
|
- name: Lint
|
||||||
|
run: |
|
||||||
|
npm run lint -w @goauthentik/web
|
||||||
|
npm run lint:lockfile -w @goauthentik/web
|
||||||
|
npm run lit-analyse -w @goauthentik/web
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: package.json
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: package-lock.json
|
||||||
|
- name: Install Node.js dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Generate TypeScript API
|
||||||
run: make gen-client-ts
|
run: make gen-client-ts
|
||||||
- name: build
|
- name: build
|
||||||
working-directory: web/
|
run: |
|
||||||
run: npm run build
|
npm run build -w @goauthentik/web
|
||||||
|
npm run typecheck
|
||||||
ci-web-mark:
|
ci-web-mark:
|
||||||
|
name: CI Web Mark
|
||||||
if: always()
|
if: always()
|
||||||
needs:
|
needs:
|
||||||
- build
|
- build
|
||||||
@ -71,6 +67,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
jobs: ${{ toJSON(needs) }}
|
jobs: ${{ toJSON(needs) }}
|
||||||
test:
|
test:
|
||||||
|
name: Test
|
||||||
needs:
|
needs:
|
||||||
- ci-web-mark
|
- ci-web-mark
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -78,13 +75,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: web/package.json
|
node-version-file: package.json
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
cache-dependency-path: web/package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- working-directory: web/
|
- name: Install Node.js dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Generate API
|
- name: Generate TypeScript API
|
||||||
run: make gen-client-ts
|
run: make gen-client-ts
|
||||||
- name: test
|
- name: Test Web UI
|
||||||
working-directory: web/
|
run: npm run test -w @goauthentik/web || exit 0
|
||||||
run: npm run test || exit 0
|
|
||||||
|
66
.github/workflows/ci-website.yml
vendored
66
.github/workflows/ci-website.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-ci-website
|
name: CI Docs Website
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -13,55 +13,59 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
|
name: "Lint"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
command:
|
|
||||||
- lint:lockfile
|
|
||||||
- prettier-check
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- working-directory: website/
|
- uses: actions/setup-node@v4
|
||||||
run: npm ci
|
with:
|
||||||
- name: Lint
|
node-version-file: package.json
|
||||||
working-directory: website/
|
cache: "npm"
|
||||||
run: npm run ${{ matrix.command }}
|
cache-dependency-path: package-lock.json
|
||||||
|
- name: Install Node.js dependencies
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
- name: Generate TypeScript API
|
||||||
|
run: make gen-client-ts
|
||||||
|
- name: Lint Docs
|
||||||
|
run: |
|
||||||
|
npm run lint:prettier:check
|
||||||
|
npm run lint:lockfile -w @goauthentik/docs
|
||||||
test:
|
test:
|
||||||
|
name: "Test Docs"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: website/package.json
|
node-version-file: package.json
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
cache-dependency-path: website/package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- working-directory: website/
|
- name: Install Node.js dependencies
|
||||||
run: npm ci
|
run: |
|
||||||
- name: test
|
npm ci
|
||||||
working-directory: website/
|
- name: Generate TypeScript API
|
||||||
run: npm test
|
run: make gen-client-ts
|
||||||
|
- name: Test Docs
|
||||||
|
run: |
|
||||||
|
npm run test -w @goauthentik/docs
|
||||||
build:
|
build:
|
||||||
|
name: "Build Docs"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: ${{ matrix.job }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
job:
|
|
||||||
- build
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: website/package.json
|
node-version-file: package.json
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
cache-dependency-path: website/package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- working-directory: website/
|
- name: Install Node.js dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: build
|
- name: Build
|
||||||
working-directory: website/
|
run: |
|
||||||
run: npm run ${{ matrix.job }}
|
npm run build -w @goauthentik/docs
|
||||||
ci-website-mark:
|
ci-website-mark:
|
||||||
|
name: "CI Website Mark"
|
||||||
if: always()
|
if: always()
|
||||||
needs:
|
needs:
|
||||||
- lint
|
- lint
|
||||||
|
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -10,7 +10,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
name: Analyze
|
name: "Analyze"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
name: authentik-gen-update-webauthn-mds
|
name: "authentik CI Update WebAuthn MDS"
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
@ -11,6 +11,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: "Update WebAuthn MDS"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
3
.github/workflows/gha-cache-cleanup.yml
vendored
3
.github/workflows/gha-cache-cleanup.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# See https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
|
# See https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
|
||||||
name: Cleanup cache after PR is closed
|
name: "Post-PR Closed Cache Cleanup"
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
@ -12,6 +12,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cleanup:
|
cleanup:
|
||||||
|
name: "Cleanup Cache"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
|
4
.github/workflows/ghcr-retention.yml
vendored
4
.github/workflows/ghcr-retention.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: ghcr-retention
|
name: "authentik GHCR Retention Policy"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# schedule:
|
# schedule:
|
||||||
@ -8,7 +8,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
clean-ghcr:
|
clean-ghcr:
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
name: Delete old unused container images
|
name: "Delete old unused container images"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- id: generate_token
|
- id: generate_token
|
||||||
|
4
.github/workflows/image-compress.yml
vendored
4
.github/workflows/image-compress.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-compress-images
|
name: "authentik CI Image Compression"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -20,7 +20,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
compress:
|
compress:
|
||||||
name: compress
|
name: "Compress Docker images"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# Don't run on forks. Token will not be available. Will run on main and open a PR anyway
|
# Don't run on forks. Token will not be available. Will run on main and open a PR anyway
|
||||||
if: |
|
if: |
|
||||||
|
7
.github/workflows/publish-source-docs.yml
vendored
7
.github/workflows/publish-source-docs.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-publish-source-docs
|
name: "authentik Publish Source Docs"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -12,6 +12,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-source-docs:
|
publish-source-docs:
|
||||||
|
name: "Publish"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
@ -19,11 +20,11 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup authentik env
|
- name: Setup authentik env
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
- name: generate docs
|
- name: Generate docs
|
||||||
run: |
|
run: |
|
||||||
uv run make migrate
|
uv run make migrate
|
||||||
uv run ak build_source_docs
|
uv run ak build_source_docs
|
||||||
- name: Publish
|
- name: Deploy to Netlify
|
||||||
uses: netlify/actions/cli@master
|
uses: netlify/actions/cli@master
|
||||||
with:
|
with:
|
||||||
args: deploy --dir=source_docs --prod
|
args: deploy --dir=source_docs --prod
|
||||||
|
3
.github/workflows/release-next-branch.yml
vendored
3
.github/workflows/release-next-branch.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-on-release-next-branch
|
name: "authentik on Release Next Branch"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
@ -11,6 +11,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-next:
|
update-next:
|
||||||
|
name: "Update Next Branch"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: internal-production
|
environment: internal-production
|
||||||
|
21
.github/workflows/release-publish.yml
vendored
21
.github/workflows/release-publish.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-on-release
|
name: "Release publish"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
@ -7,6 +7,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-server:
|
build-server:
|
||||||
|
name: "Build server"
|
||||||
uses: ./.github/workflows/_reusable-docker-build.yaml
|
uses: ./.github/workflows/_reusable-docker-build.yaml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
permissions:
|
permissions:
|
||||||
@ -21,6 +22,7 @@ jobs:
|
|||||||
registry_dockerhub: true
|
registry_dockerhub: true
|
||||||
registry_ghcr: true
|
registry_ghcr: true
|
||||||
build-outpost:
|
build-outpost:
|
||||||
|
name: "Build outpost"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
# Needed to upload container images to ghcr.io
|
# Needed to upload container images to ghcr.io
|
||||||
@ -45,14 +47,14 @@ jobs:
|
|||||||
uses: docker/setup-qemu-action@v3.6.0
|
uses: docker/setup-qemu-action@v3.6.0
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||||
with:
|
with:
|
||||||
image-name: ghcr.io/goauthentik/${{ matrix.type }},beryju/authentik-${{ matrix.type }}
|
image-name: ghcr.io/goauthentik/${{ matrix.type }},beryju/authentik-${{ matrix.type }}
|
||||||
- name: make empty clients
|
- name: Make empty clients
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ./gen-ts-api
|
mkdir -p ./gen-ts-api
|
||||||
mkdir -p ./gen-go-api
|
mkdir -p ./gen-go-api
|
||||||
@ -85,6 +87,7 @@ jobs:
|
|||||||
subject-digest: ${{ steps.push.outputs.digest }}
|
subject-digest: ${{ steps.push.outputs.digest }}
|
||||||
push-to-registry: true
|
push-to-registry: true
|
||||||
build-outpost-binary:
|
build-outpost-binary:
|
||||||
|
name: "Build outpost binary"
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
@ -106,14 +109,13 @@ jobs:
|
|||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: web/package.json
|
node-version-file: package.json
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
cache-dependency-path: web/package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- name: Build web
|
- name: Build web
|
||||||
working-directory: web/
|
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
npm run build-proxy
|
npm run build-proxy -w @goauthentik/web
|
||||||
- name: Build outpost
|
- name: Build outpost
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
@ -129,6 +131,7 @@ jobs:
|
|||||||
asset_name: authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }}
|
asset_name: authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }}
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
upload-aws-cfn-template:
|
upload-aws-cfn-template:
|
||||||
|
name: "Upload AWS CloudFormation template"
|
||||||
permissions:
|
permissions:
|
||||||
# Needed for AWS login
|
# Needed for AWS login
|
||||||
id-token: write
|
id-token: write
|
||||||
@ -150,6 +153,7 @@ jobs:
|
|||||||
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.${{ github.ref }}.yaml
|
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.${{ github.ref }}.yaml
|
||||||
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.latest.yaml
|
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.latest.yaml
|
||||||
test-release:
|
test-release:
|
||||||
|
name: "Test release"
|
||||||
needs:
|
needs:
|
||||||
- build-server
|
- build-server
|
||||||
- build-outpost
|
- build-outpost
|
||||||
@ -166,6 +170,7 @@ jobs:
|
|||||||
docker compose start postgresql redis
|
docker compose start postgresql redis
|
||||||
docker compose run -u root server test-all
|
docker compose run -u root server test-all
|
||||||
sentry-release:
|
sentry-release:
|
||||||
|
name: "Sentry release"
|
||||||
needs:
|
needs:
|
||||||
- build-server
|
- build-server
|
||||||
- build-outpost
|
- build-outpost
|
||||||
@ -173,7 +178,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
|
6
.github/workflows/release-tag.yml
vendored
6
.github/workflows/release-tag.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-on-tag
|
name: "authentik on Tag Release"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -8,7 +8,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Create Release from Tag
|
name: "Create Release from Tag"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -20,7 +20,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
app_id: ${{ secrets.GH_APP_ID }}
|
app_id: ${{ secrets.GH_APP_ID }}
|
||||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
- name: prepare variables
|
- name: Prepare variables
|
||||||
uses: ./.github/actions/docker-push-variables
|
uses: ./.github/actions/docker-push-variables
|
||||||
id: ev
|
id: ev
|
||||||
env:
|
env:
|
||||||
|
4
.github/workflows/repo-mirror.yml
vendored
4
.github/workflows/repo-mirror.yml
vendored
@ -1,13 +1,15 @@
|
|||||||
name: "authentik-repo-mirror"
|
name: "authentik Repository Mirror"
|
||||||
|
|
||||||
on: [push, delete]
|
on: [push, delete]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
to_internal:
|
to_internal:
|
||||||
|
name: "Mirror to internal repository"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
name: "Checkout repository"
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- if: ${{ env.MIRROR_KEY != '' }}
|
- if: ${{ env.MIRROR_KEY != '' }}
|
||||||
|
3
.github/workflows/repo-stale.yml
vendored
3
.github/workflows/repo-stale.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: "authentik-repo-stale"
|
name: "authentik Repository Stale Issues"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
@ -11,6 +11,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
|
name: "Stale Issues"
|
||||||
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
4
.github/workflows/semgrep.yml
vendored
4
.github/workflows/semgrep.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-semgrep
|
name: "authentik CI Semgrep"
|
||||||
on:
|
on:
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
pull_request: {}
|
pull_request: {}
|
||||||
@ -13,7 +13,7 @@ on:
|
|||||||
- cron: '12 15 * * *'
|
- cron: '12 15 * * *'
|
||||||
jobs:
|
jobs:
|
||||||
semgrep:
|
semgrep:
|
||||||
name: semgrep/ci
|
name: "semgrep/ci"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
3
.github/workflows/translation-advice.yml
vendored
3
.github/workflows/translation-advice.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: authentik-translation-advice
|
name: "authentik Translations Advice"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -16,6 +16,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
post-comment:
|
post-comment:
|
||||||
|
name: "Post Comment"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Find Comment
|
- name: Find Comment
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: authentik-translate-extract-compile
|
name: "authentik Extract & Compile Translations"
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *" # every day at midnight
|
- cron: "0 0 * * *" # every day at midnight
|
||||||
@ -16,6 +16,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
compile:
|
compile:
|
||||||
|
name: "Compile Translations"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- id: generate_token
|
- id: generate_token
|
||||||
@ -32,15 +33,20 @@ jobs:
|
|||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
- name: Setup authentik env
|
- name: Setup authentik env
|
||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
- name: Generate API
|
- name: Generate TypeScript API
|
||||||
run: make gen-client-ts
|
run: make gen-client-ts
|
||||||
- name: run extract
|
- name: Extract Translations
|
||||||
run: |
|
run: |
|
||||||
uv run make i18n-extract
|
uv run make i18n-extract
|
||||||
- name: run compile
|
- name: Build Docs Site
|
||||||
|
run: npm run build-bundled -w @goauthentik/docs
|
||||||
|
- name: Build Web UI
|
||||||
|
run: npm run build -w @goauthentik/web
|
||||||
|
- name: Type check
|
||||||
|
run: npm run typecheck
|
||||||
|
- name: Compile Messages
|
||||||
run: |
|
run: |
|
||||||
uv run ak compilemessages
|
uv run ak compilemessages
|
||||||
make web-check-compile
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
3
.github/workflows/translation-rename.yml
vendored
3
.github/workflows/translation-rename.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
# Rename transifex pull requests to have a correct naming
|
# Rename transifex pull requests to have a correct naming
|
||||||
# Also enables auto squash-merge
|
# Also enables auto squash-merge
|
||||||
name: authentik-translation-transifex-rename
|
name: "authentik Translations Transifex PR Rename"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -12,6 +12,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
rename_pr:
|
rename_pr:
|
||||||
|
name: "Rename PR"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event.pull_request.user.login == 'transifex-integration[bot]'}}
|
if: ${{ github.event.pull_request.user.login == 'transifex-integration[bot]'}}
|
||||||
steps:
|
steps:
|
||||||
|
23
.gitignore
vendored
23
.gitignore
vendored
@ -217,3 +217,26 @@ source_docs/
|
|||||||
|
|
||||||
### Docker ###
|
### Docker ###
|
||||||
docker-compose.override.yml
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
|
||||||
|
### Node ###
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
tsconfig.tsbuildinfo
|
||||||
|
|
||||||
|
# Wireit's cache
|
||||||
|
.wireit
|
||||||
|
|
||||||
|
custom-elements.json
|
||||||
|
|
||||||
|
|
||||||
|
### Development ###
|
||||||
|
.drafts
|
||||||
|
@ -4,12 +4,16 @@
|
|||||||
**/LICENSE
|
**/LICENSE
|
||||||
|
|
||||||
authentik/stages/**/*
|
authentik/stages/**/*
|
||||||
|
authentik/sources/**/*
|
||||||
|
schemas/**/*
|
||||||
|
blueprints/**/*
|
||||||
|
|
||||||
## Build asset directories
|
## Build asset directories
|
||||||
coverage
|
coverage
|
||||||
dist
|
dist
|
||||||
out
|
out
|
||||||
.docusaurus
|
.docusaurus
|
||||||
|
.wireit
|
||||||
website/docs/developer-docs/api/**/*
|
website/docs/developer-docs/api/**/*
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
@ -32,14 +36,15 @@ coverage
|
|||||||
|
|
||||||
# Templates
|
# Templates
|
||||||
# TODO: Rename affected files to *.template.* or similar.
|
# TODO: Rename affected files to *.template.* or similar.
|
||||||
|
authentik/**/*.html
|
||||||
*.html
|
*.html
|
||||||
*.mdx
|
*.mdx
|
||||||
*.md
|
*.md
|
||||||
|
|
||||||
## Import order matters
|
## Import order matters
|
||||||
poly.ts
|
web/src/poly.ts
|
||||||
src/locale-codes.ts
|
web/src/locale-codes.ts
|
||||||
src/locales/
|
web/src/locales/
|
||||||
|
|
||||||
# Storybook
|
# Storybook
|
||||||
storybook-static/
|
storybook-static/
|
||||||
|
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@ -17,6 +17,6 @@
|
|||||||
"ms-python.vscode-pylance",
|
"ms-python.vscode-pylance",
|
||||||
"redhat.vscode-yaml",
|
"redhat.vscode-yaml",
|
||||||
"Tobermory.es6-string-html",
|
"Tobermory.es6-string-html",
|
||||||
"unifiedjs.vscode-mdx",
|
"unifiedjs.vscode-mdx"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
72
.vscode/settings.json
vendored
72
.vscode/settings.json
vendored
@ -16,7 +16,7 @@
|
|||||||
],
|
],
|
||||||
"typescript.preferences.importModuleSpecifier": "non-relative",
|
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||||
"typescript.preferences.importModuleSpecifierEnding": "index",
|
"typescript.preferences.importModuleSpecifierEnding": "index",
|
||||||
"typescript.tsdk": "./web/node_modules/typescript/lib",
|
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||||
"yaml.schemas": {
|
"yaml.schemas": {
|
||||||
"./blueprints/schema.json": "blueprints/**/*.yaml"
|
"./blueprints/schema.json": "blueprints/**/*.yaml"
|
||||||
@ -30,7 +30,71 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"go.testFlags": ["-count=1"],
|
"go.testFlags": ["-count=1"],
|
||||||
"github-actions.workflows.pinned.workflows": [
|
"github-actions.workflows.pinned.workflows": [".github/workflows/ci-main.yml"],
|
||||||
".github/workflows/ci-main.yml"
|
|
||||||
]
|
"eslint.useFlatConfig": true,
|
||||||
|
|
||||||
|
"explorer.fileNesting.enabled": true,
|
||||||
|
"explorer.fileNesting.patterns": {
|
||||||
|
"*.mjs": "*.d.mts",
|
||||||
|
"*.cjs": "*.d.cts",
|
||||||
|
"package.json": "package-lock.json, yarn.lock, .yarnrc, .yarnrc.yml, .yarn, .nvmrc, .node-version",
|
||||||
|
"tsconfig.json": "tsconfig.*.json, jsconfig.json",
|
||||||
|
"Dockerfile": "*.Dockerfile"
|
||||||
|
},
|
||||||
|
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"**/*.code-search": true,
|
||||||
|
"**/dist": true,
|
||||||
|
"**/out": true,
|
||||||
|
"**/package-lock.json": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"[css]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[markdown]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[shellscript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[typescriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[django-html]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.removeUnusedImports": "explicit"
|
||||||
|
},
|
||||||
|
// We use Prettier for formatting, but specifying these settings
|
||||||
|
// will ensure that VS Code's IntelliSense doesn't autocomplete unformatted code.
|
||||||
|
"javascript.format.semicolons": "insert",
|
||||||
|
"typescript.format.semicolons": "insert",
|
||||||
|
"javascript.preferences.quoteStyle": "double",
|
||||||
|
"typescript.preferences.quoteStyle": "double",
|
||||||
|
"github.copilot.enable": {
|
||||||
|
"*": true,
|
||||||
|
"plaintext": true,
|
||||||
|
"markdown": true,
|
||||||
|
"scminput": false,
|
||||||
|
"csv": false,
|
||||||
|
"json": true,
|
||||||
|
"yaml": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
40
.vscode/tasks.json
vendored
40
.vscode/tasks.json
vendored
@ -4,12 +4,7 @@
|
|||||||
{
|
{
|
||||||
"label": "authentik/core: make",
|
"label": "authentik/core: make",
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": [
|
"args": ["run", "make", "lint-fix", "lint"],
|
||||||
"run",
|
|
||||||
"make",
|
|
||||||
"lint-fix",
|
|
||||||
"lint"
|
|
||||||
],
|
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"panel": "new"
|
"panel": "new"
|
||||||
},
|
},
|
||||||
@ -18,11 +13,7 @@
|
|||||||
{
|
{
|
||||||
"label": "authentik/core: run",
|
"label": "authentik/core: run",
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": [
|
"args": ["run", "ak", "server"],
|
||||||
"run",
|
|
||||||
"ak",
|
|
||||||
"server"
|
|
||||||
],
|
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"panel": "dedicated",
|
"panel": "dedicated",
|
||||||
@ -32,17 +23,13 @@
|
|||||||
{
|
{
|
||||||
"label": "authentik/web: make",
|
"label": "authentik/web: make",
|
||||||
"command": "make",
|
"command": "make",
|
||||||
"args": [
|
"args": ["web"],
|
||||||
"web"
|
|
||||||
],
|
|
||||||
"group": "build"
|
"group": "build"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "authentik/web: watch",
|
"label": "authentik/web: watch",
|
||||||
"command": "make",
|
"command": "make",
|
||||||
"args": [
|
"args": ["web-watch"],
|
||||||
"web-watch"
|
|
||||||
],
|
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"panel": "dedicated",
|
"panel": "dedicated",
|
||||||
@ -52,26 +39,19 @@
|
|||||||
{
|
{
|
||||||
"label": "authentik: install",
|
"label": "authentik: install",
|
||||||
"command": "make",
|
"command": "make",
|
||||||
"args": [
|
"args": ["install", "-j4"],
|
||||||
"install",
|
|
||||||
"-j4"
|
|
||||||
],
|
|
||||||
"group": "build"
|
"group": "build"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "authentik/website: make",
|
"label": "authentik/website: make",
|
||||||
"command": "make",
|
"command": "make",
|
||||||
"args": [
|
"args": ["website"],
|
||||||
"website"
|
|
||||||
],
|
|
||||||
"group": "build"
|
"group": "build"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "authentik/website: watch",
|
"label": "authentik/website: watch",
|
||||||
"command": "make",
|
"command": "make",
|
||||||
"args": [
|
"args": ["website-watch"],
|
||||||
"website-watch"
|
|
||||||
],
|
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"panel": "dedicated",
|
"panel": "dedicated",
|
||||||
@ -81,11 +61,7 @@
|
|||||||
{
|
{
|
||||||
"label": "authentik/api: generate",
|
"label": "authentik/api: generate",
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": [
|
"args": ["run", "make", "gen"],
|
||||||
"run",
|
|
||||||
"make",
|
|
||||||
"gen"
|
|
||||||
],
|
|
||||||
"group": "build"
|
"group": "build"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
65
Dockerfile
65
Dockerfile
@ -1,48 +1,31 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
# Stage 1: Build website
|
# Stage 1 Web UI and Documentation build
|
||||||
FROM --platform=${BUILDPLATFORM} docker.io/library/node:22 AS website-builder
|
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
|
|
||||||
WORKDIR /work/website
|
|
||||||
|
|
||||||
RUN --mount=type=bind,target=/work/website/package.json,src=./website/package.json \
|
|
||||||
--mount=type=bind,target=/work/website/package-lock.json,src=./website/package-lock.json \
|
|
||||||
--mount=type=cache,id=npm-website,sharing=shared,target=/root/.npm \
|
|
||||||
npm ci --include=dev
|
|
||||||
|
|
||||||
COPY ./website /work/website/
|
|
||||||
COPY ./blueprints /work/blueprints/
|
|
||||||
COPY ./schema.yml /work/
|
|
||||||
COPY ./SECURITY.md /work/
|
|
||||||
|
|
||||||
RUN npm run build-bundled
|
|
||||||
|
|
||||||
# Stage 2: Build webui
|
|
||||||
FROM --platform=${BUILDPLATFORM} docker.io/library/node:22 AS web-builder
|
FROM --platform=${BUILDPLATFORM} docker.io/library/node:22 AS web-builder
|
||||||
|
|
||||||
ARG GIT_BUILD_HASH
|
|
||||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
WORKDIR /work/web
|
WORKDIR /work
|
||||||
|
|
||||||
RUN --mount=type=bind,target=/work/web/package.json,src=./web/package.json \
|
COPY ./package.json ./package.json
|
||||||
--mount=type=bind,target=/work/web/package-lock.json,src=./web/package-lock.json \
|
COPY ./package-lock.json ./package-lock.json
|
||||||
--mount=type=bind,target=/work/web/packages/sfe/package.json,src=./web/packages/sfe/package.json \
|
COPY ./packages ./packages
|
||||||
--mount=type=bind,target=/work/web/scripts,src=./web/scripts \
|
COPY ./web ./web
|
||||||
--mount=type=cache,id=npm-web,sharing=shared,target=/root/.npm \
|
COPY ./website ./website
|
||||||
npm ci --include=dev
|
|
||||||
|
|
||||||
COPY ./package.json /work
|
COPY ./gen-ts-api ./gen-ts-api
|
||||||
COPY ./web /work/web/
|
COPY ./blueprints ./blueprints
|
||||||
COPY ./website /work/website/
|
COPY ./schema.yml ./schema.yml
|
||||||
COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
|
COPY ./SECURITY.md ./SECURITY.md
|
||||||
|
|
||||||
RUN npm run build
|
RUN --mount=type=cache,target=/root/.npm npm ci --include=dev
|
||||||
|
|
||||||
|
RUN npm run build-bundled -w @goauthentik/docs
|
||||||
|
RUN npm run build -w @goauthentik/web
|
||||||
|
|
||||||
|
# Stage 2: Build go proxy
|
||||||
|
|
||||||
# Stage 3: Build go proxy
|
|
||||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS go-builder
|
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS go-builder
|
||||||
|
|
||||||
ARG TARGETOS
|
ARG TARGETOS
|
||||||
@ -79,7 +62,8 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
|||||||
CGO_ENABLED=1 GOFIPS140=latest GOARM="${TARGETVARIANT#v}" \
|
CGO_ENABLED=1 GOFIPS140=latest GOARM="${TARGETVARIANT#v}" \
|
||||||
go build -o /go/authentik ./cmd/server
|
go build -o /go/authentik ./cmd/server
|
||||||
|
|
||||||
# Stage 4: MaxMind GeoIP
|
# Stage 3: MaxMind GeoIP
|
||||||
|
|
||||||
FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.1.0 AS geoip
|
FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.1.0 AS geoip
|
||||||
|
|
||||||
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
|
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
|
||||||
@ -93,9 +77,10 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
|
|||||||
mkdir -p /usr/share/GeoIP && \
|
mkdir -p /usr/share/GeoIP && \
|
||||||
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
|
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
|
||||||
|
|
||||||
# Stage 5: Download uv
|
# Stage 4: Download uv
|
||||||
FROM ghcr.io/astral-sh/uv:0.6.14 AS uv
|
FROM ghcr.io/astral-sh/uv:0.6.14 AS uv
|
||||||
# Stage 6: Base python image
|
|
||||||
|
# Stage 5: Base python image
|
||||||
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base
|
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base
|
||||||
|
|
||||||
ENV VENV_PATH="/ak-root/.venv" \
|
ENV VENV_PATH="/ak-root/.venv" \
|
||||||
@ -109,7 +94,7 @@ WORKDIR /ak-root/
|
|||||||
|
|
||||||
COPY --from=uv /uv /uvx /bin/
|
COPY --from=uv /uv /uvx /bin/
|
||||||
|
|
||||||
# Stage 7: Python dependencies
|
# Stage 6: Python dependencies
|
||||||
FROM python-base AS python-deps
|
FROM python-base AS python-deps
|
||||||
|
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
@ -144,7 +129,7 @@ RUN --mount=type=bind,target=pyproject.toml,src=pyproject.toml \
|
|||||||
--mount=type=cache,target=/root/.cache/uv \
|
--mount=type=cache,target=/root/.cache/uv \
|
||||||
uv sync --frozen --no-install-project --no-dev
|
uv sync --frozen --no-install-project --no-dev
|
||||||
|
|
||||||
# Stage 8: Run
|
# Stage 7: Run
|
||||||
FROM python-base AS final-image
|
FROM python-base AS final-image
|
||||||
|
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
@ -189,7 +174,7 @@ COPY --from=go-builder /go/authentik /bin/authentik
|
|||||||
COPY --from=python-deps /ak-root/.venv /ak-root/.venv
|
COPY --from=python-deps /ak-root/.venv /ak-root/.venv
|
||||||
COPY --from=web-builder /work/web/dist/ /web/dist/
|
COPY --from=web-builder /work/web/dist/ /web/dist/
|
||||||
COPY --from=web-builder /work/web/authentik/ /web/authentik/
|
COPY --from=web-builder /work/web/authentik/ /web/authentik/
|
||||||
COPY --from=website-builder /work/website/build/ /website/help/
|
COPY --from=web-builder /work/website/build/ /website/help/
|
||||||
COPY --from=geoip /usr/share/GeoIP /geoip
|
COPY --from=geoip /usr/share/GeoIP /geoip
|
||||||
|
|
||||||
USER 1000
|
USER 1000
|
||||||
|
107
Makefile
107
Makefile
@ -36,6 +36,13 @@ test: ## Run the server tests and produce a coverage report (locally)
|
|||||||
uv run coverage html
|
uv run coverage html
|
||||||
uv run coverage report
|
uv run coverage report
|
||||||
|
|
||||||
|
node-check-compile: ## Check and compile the TypeScript source code
|
||||||
|
npm run typecheck
|
||||||
|
|
||||||
|
node-lint-fix: ## Lint and automatically fix errors in the javascript source code
|
||||||
|
lint-codespell
|
||||||
|
npm run lint:fix
|
||||||
|
|
||||||
lint-fix: lint-codespell ## Lint and automatically fix errors in the python source code. Reports spelling errors.
|
lint-fix: lint-codespell ## Lint and automatically fix errors in the python source code. Reports spelling errors.
|
||||||
uv run black $(PY_SOURCES)
|
uv run black $(PY_SOURCES)
|
||||||
uv run ruff check --fix $(PY_SOURCES)
|
uv run ruff check --fix $(PY_SOURCES)
|
||||||
@ -47,9 +54,6 @@ lint: ## Lint the python and golang sources
|
|||||||
uv run bandit -c pyproject.toml -r $(PY_SOURCES)
|
uv run bandit -c pyproject.toml -r $(PY_SOURCES)
|
||||||
golangci-lint run -v
|
golangci-lint run -v
|
||||||
|
|
||||||
core-install:
|
|
||||||
uv sync --frozen
|
|
||||||
|
|
||||||
migrate: ## Run the Authentik Django server's migrations
|
migrate: ## Run the Authentik Django server's migrations
|
||||||
uv run python -m lifecycle.migrate
|
uv run python -m lifecycle.migrate
|
||||||
|
|
||||||
@ -72,7 +76,9 @@ core-i18n-extract:
|
|||||||
--ignore website \
|
--ignore website \
|
||||||
-l en
|
-l en
|
||||||
|
|
||||||
install: web-install website-install core-install ## Install all requires dependencies for `web`, `website` and `core`
|
install: ## Install all requires dependencies for `web`, `website` and `core`
|
||||||
|
npm ci
|
||||||
|
uv sync --frozen
|
||||||
|
|
||||||
dev-drop-db:
|
dev-drop-db:
|
||||||
dropdb -U ${pg_user} -h ${pg_host} ${pg_name}
|
dropdb -U ${pg_user} -h ${pg_host} ${pg_name}
|
||||||
@ -94,6 +100,7 @@ gen-build: ## Extract the schema from the database
|
|||||||
AUTHENTIK_TENANTS__ENABLED=true \
|
AUTHENTIK_TENANTS__ENABLED=true \
|
||||||
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
|
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
|
||||||
uv run ak make_blueprint_schema > blueprints/schema.json
|
uv run ak make_blueprint_schema > blueprints/schema.json
|
||||||
|
|
||||||
AUTHENTIK_DEBUG=true \
|
AUTHENTIK_DEBUG=true \
|
||||||
AUTHENTIK_TENANTS__ENABLED=true \
|
AUTHENTIK_TENANTS__ENABLED=true \
|
||||||
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
|
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
|
||||||
@ -101,19 +108,24 @@ gen-build: ## Extract the schema from the database
|
|||||||
|
|
||||||
gen-changelog: ## (Release) generate the changelog based from the commits since the last tag
|
gen-changelog: ## (Release) generate the changelog based from the commits since the last tag
|
||||||
git log --pretty=format:" - %s" $(shell git describe --tags $(shell git rev-list --tags --max-count=1))...$(shell git branch --show-current) | sort > changelog.md
|
git log --pretty=format:" - %s" $(shell git describe --tags $(shell git rev-list --tags --max-count=1))...$(shell git branch --show-current) | sort > changelog.md
|
||||||
|
|
||||||
npx prettier --write changelog.md
|
npx prettier --write changelog.md
|
||||||
|
|
||||||
gen-diff: ## (Release) generate the changelog diff between the current schema and the last tag
|
gen-diff: ## (Release) generate the changelog diff between the current schema and the last tag
|
||||||
git show $(shell git describe --tags $(shell git rev-list --tags --max-count=1)):schema.yml > old_schema.yml
|
git show $(shell git describe --tags $(shell git rev-list --tags --max-count=1)):schema.yml > old_schema.yml
|
||||||
|
|
||||||
docker run \
|
docker run \
|
||||||
--rm -v ${PWD}:/local \
|
--rm -v ${PWD}:/local \
|
||||||
--user ${UID}:${GID} \
|
--user ${UID}:${GID} \
|
||||||
docker.io/openapitools/openapi-diff:2.1.0-beta.8 \
|
docker.io/openapitools/openapi-diff:2.1.0-beta.8 \
|
||||||
--markdown /local/diff.md \
|
--markdown /local/diff.md \
|
||||||
/local/old_schema.yml /local/schema.yml
|
/local/old_schema.yml /local/schema.yml
|
||||||
|
|
||||||
rm old_schema.yml
|
rm old_schema.yml
|
||||||
|
|
||||||
sed -i 's/{/{/g' diff.md
|
sed -i 's/{/{/g' diff.md
|
||||||
sed -i 's/}/}/g' diff.md
|
sed -i 's/}/}/g' diff.md
|
||||||
|
|
||||||
npx prettier --write diff.md
|
npx prettier --write diff.md
|
||||||
|
|
||||||
gen-clean-ts: ## Remove generated API client for Typescript
|
gen-clean-ts: ## Remove generated API client for Typescript
|
||||||
@ -133,46 +145,57 @@ gen-client-ts: gen-clean-ts ## Build and install the authentik API for Typescri
|
|||||||
--rm -v ${PWD}:/local \
|
--rm -v ${PWD}:/local \
|
||||||
--user ${UID}:${GID} \
|
--user ${UID}:${GID} \
|
||||||
docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \
|
docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \
|
||||||
-i /local/schema.yml \
|
--input-spec /local/schema.yml \
|
||||||
-g typescript-fetch \
|
--generator-name typescript-fetch \
|
||||||
-o /local/${GEN_API_TS} \
|
--output /local/${GEN_API_TS} \
|
||||||
-c /local/scripts/api-ts-config.yaml \
|
--config /local/scripts/api-ts-config.yaml \
|
||||||
--additional-properties=npmVersion=${NPM_VERSION} \
|
--additional-properties=npmVersion=${NPM_VERSION} \
|
||||||
--git-repo-id authentik \
|
--git-repo-id authentik \
|
||||||
--git-user-id goauthentik
|
--git-user-id goauthentik
|
||||||
mkdir -p web/node_modules/@goauthentik/api
|
|
||||||
cd ./${GEN_API_TS} && npm i
|
npm install
|
||||||
\cp -rf ./${GEN_API_TS}/* web/node_modules/@goauthentik/api
|
|
||||||
|
|
||||||
gen-client-py: gen-clean-py ## Build and install the authentik API for Python
|
gen-client-py: gen-clean-py ## Build and install the authentik API for Python
|
||||||
|
|
||||||
docker run \
|
docker run \
|
||||||
--rm -v ${PWD}:/local \
|
--rm -v ${PWD}:/local \
|
||||||
--user ${UID}:${GID} \
|
--user ${UID}:${GID} \
|
||||||
docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \
|
docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \
|
||||||
-i /local/schema.yml \
|
--input-spec /local/schema.yml \
|
||||||
-g python \
|
--generator-name python \
|
||||||
-o /local/${GEN_API_PY} \
|
--output /local/${GEN_API_PY} \
|
||||||
-c /local/scripts/api-py-config.yaml \
|
--config /local/scripts/api-py-config.yaml \
|
||||||
--additional-properties=packageVersion=${NPM_VERSION} \
|
--additional-properties=packageVersion=${NPM_VERSION} \
|
||||||
--git-repo-id authentik \
|
--git-repo-id authentik \
|
||||||
--git-user-id goauthentik
|
--git-user-id goauthentik
|
||||||
|
|
||||||
pip install ./${GEN_API_PY}
|
pip install ./${GEN_API_PY}
|
||||||
|
|
||||||
gen-client-go: gen-clean-go ## Build and install the authentik API for Golang
|
gen-client-go: gen-clean-go ## Build and install the authentik API for Golang
|
||||||
mkdir -p ./${GEN_API_GO} ./${GEN_API_GO}/templates
|
mkdir -p ./${GEN_API_GO} ./${GEN_API_GO}/templates
|
||||||
wget https://raw.githubusercontent.com/goauthentik/client-go/main/config.yaml -O ./${GEN_API_GO}/config.yaml
|
|
||||||
wget https://raw.githubusercontent.com/goauthentik/client-go/main/templates/README.mustache -O ./${GEN_API_GO}/templates/README.mustache
|
wget https://raw.githubusercontent.com/goauthentik/client-go/main/config.yaml \
|
||||||
wget https://raw.githubusercontent.com/goauthentik/client-go/main/templates/go.mod.mustache -O ./${GEN_API_GO}/templates/go.mod.mustache
|
-O ./${GEN_API_GO}/config.yaml
|
||||||
|
|
||||||
|
wget https://raw.githubusercontent.com/goauthentik/client-go/main/templates/README.mustache \
|
||||||
|
-O ./${GEN_API_GO}/templates/README.mustache
|
||||||
|
|
||||||
|
wget https://raw.githubusercontent.com/goauthentik/client-go/main/templates/go.mod.mustache \
|
||||||
|
-O ./${GEN_API_GO}/templates/go.mod.mustache
|
||||||
|
|
||||||
cp schema.yml ./${GEN_API_GO}/
|
cp schema.yml ./${GEN_API_GO}/
|
||||||
|
|
||||||
docker run \
|
docker run \
|
||||||
--rm -v ${PWD}/${GEN_API_GO}:/local \
|
--rm -v ${PWD}/${GEN_API_GO}:/local \
|
||||||
--user ${UID}:${GID} \
|
--user ${UID}:${GID} \
|
||||||
docker.io/openapitools/openapi-generator-cli:v6.5.0 generate \
|
docker.io/openapitools/openapi-generator-cli:v6.5.0 generate \
|
||||||
-i /local/schema.yml \
|
--input-spec /local/schema.yml \
|
||||||
-g go \
|
--generator-name go \
|
||||||
-o /local/ \
|
--output /local/ \
|
||||||
-c /local/config.yaml
|
--config /local/config.yaml
|
||||||
|
|
||||||
go mod edit -replace goauthentik.io/api/v3=./${GEN_API_GO}
|
go mod edit -replace goauthentik.io/api/v3=./${GEN_API_GO}
|
||||||
|
|
||||||
rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/
|
rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/
|
||||||
|
|
||||||
gen-dev-config: ## Generate a local development config file
|
gen-dev-config: ## Generate a local development config file
|
||||||
@ -184,56 +207,38 @@ gen: gen-build gen-client-ts
|
|||||||
## Web
|
## Web
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
web-build: web-install ## Build the Authentik UI
|
web: web-lint-fix web-lint node-check-compile ## Automatically fix formatting issues in the Authentik UI source code, lint the code, and compile it
|
||||||
cd web && npm run build
|
|
||||||
|
|
||||||
web: web-lint-fix web-lint web-check-compile ## Automatically fix formatting issues in the Authentik UI source code, lint the code, and compile it
|
|
||||||
|
|
||||||
web-install: ## Install the necessary libraries to build the Authentik UI
|
|
||||||
cd web && npm ci
|
|
||||||
|
|
||||||
web-test: ## Run tests for the Authentik UI
|
web-test: ## Run tests for the Authentik UI
|
||||||
cd web && npm run test
|
npm run test -w @goauthentik/web
|
||||||
|
|
||||||
web-watch: ## Build and watch the Authentik UI for changes, updating automatically
|
web-watch: ## Build and watch the Authentik UI for changes, updating automatically
|
||||||
rm -rf web/dist/
|
npm run watch -w @goauthentik/web
|
||||||
mkdir web/dist/
|
|
||||||
touch web/dist/.gitkeep
|
|
||||||
cd web && npm run watch
|
|
||||||
|
|
||||||
web-storybook-watch: ## Build and run the storybook documentation server
|
web-storybook-watch: ## Build and run the storybook documentation server
|
||||||
cd web && npm run storybook
|
npm run storybook -w @goauthentik/web
|
||||||
|
|
||||||
web-lint-fix:
|
web-lint-fix:
|
||||||
cd web && npm run prettier
|
npm run prettier -w @goauthentik/web
|
||||||
|
|
||||||
web-lint:
|
web-lint:
|
||||||
cd web && npm run lint
|
npm run lint -w @goauthentik/web
|
||||||
cd web && npm run lit-analyse
|
npm run lit-analyse -w @goauthentik/web
|
||||||
|
|
||||||
web-check-compile:
|
|
||||||
cd web && npm run tsc
|
|
||||||
|
|
||||||
web-i18n-extract:
|
web-i18n-extract:
|
||||||
cd web && npm run extract-locales
|
npm run extract-locales -w @goauthentik/web
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
## Website
|
## Website
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
website: website-lint-fix website-build ## Automatically fix formatting issues in the Authentik website/docs source code, lint the code, and compile it
|
website: node-lint-fix website-build ## Automatically fix formatting issues in the Authentik website/docs source code, lint the code, and compile it
|
||||||
|
|
||||||
website-install:
|
|
||||||
cd website && npm ci
|
|
||||||
|
|
||||||
website-lint-fix: lint-codespell
|
|
||||||
cd website && npm run prettier
|
|
||||||
|
|
||||||
website-build:
|
website-build:
|
||||||
cd website && npm run build
|
npm run build -w @goauthentik/docs
|
||||||
|
|
||||||
website-watch: ## Build and watch the documentation website, updating automatically
|
website-watch: ## Build and watch the documentation website, updating automatically
|
||||||
cd website && npm run watch
|
npm run watch -w @goauthentik/docs
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
## Docker
|
## Docker
|
||||||
|
@ -2,20 +2,22 @@
|
|||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.authentik = {
|
window.authentik = {
|
||||||
locale: "{{ LANGUAGE_CODE }}",
|
locale: "{{ LANGUAGE_CODE }}",
|
||||||
config: JSON.parse('{{ config_json|escapejs }}'),
|
config: JSON.parse("{{ config_json|escapejs }}" || "{}"),
|
||||||
brand: JSON.parse('{{ brand_json|escapejs }}'),
|
brand: JSON.parse("{{ brand_json|escapejs }}" || "{}"),
|
||||||
versionFamily: "{{ version_family }}",
|
versionFamily: "{{ version_family }}",
|
||||||
versionSubdomain: "{{ version_subdomain }}",
|
versionSubdomain: "{{ version_subdomain }}",
|
||||||
build: "{{ build }}",
|
build: "{{ build }}",
|
||||||
api: {
|
api: {
|
||||||
base: "{{ base_url }}",
|
base: "{{ base_url }}",
|
||||||
relBase: "{{ base_url_rel }}",
|
relBase: "{{ base_url_rel }}",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
{% if messages %}
|
||||||
window.addEventListener("DOMContentLoaded", function () {
|
window.addEventListener("DOMContentLoaded", function () {
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent("ak-message", {
|
new CustomEvent("ak-message", {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
@ -26,6 +28,7 @@
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
});
|
});
|
||||||
|
{% endif %}
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,31 +2,79 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load authentik_core %}
|
{% load authentik_core %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||||
{# Darkreader breaks the site regardless of theme as its not compatible with webcomponents, and we default to a dark theme based on preferred colour-scheme #}
|
|
||||||
<meta name="darkreader-lock">
|
{% comment %}
|
||||||
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
Darkreader breaks the site regardless of theme as its not compatible with webcomponents, and we
|
||||||
<link rel="icon" href="{{ brand.branding_favicon_url }}">
|
default to a dark theme based on preferred colour-scheme
|
||||||
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}">
|
{% endcomment %}
|
||||||
{% block head_before %}
|
|
||||||
{% endblock %}
|
<meta name="darkreader-lock" />
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
|
|
||||||
<style>{{ brand.branding_custom_css }}</style>
|
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
||||||
<script src="{% versioned_script 'dist/poly-%v.js' %}" type="module"></script>
|
|
||||||
<script src="{% versioned_script 'dist/standalone/loading/index-%v.js' %}" type="module"></script>
|
<link rel="icon" href="{{ brand.branding_favicon_url }}" />
|
||||||
{% block head %}
|
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}" />
|
||||||
{% endblock %}
|
|
||||||
<meta name="sentry-trace" content="{{ sentry_trace }}" />
|
{% block head_before %}
|
||||||
</head>
|
{% endblock %}
|
||||||
<body>
|
|
||||||
{% block body %}
|
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}" />
|
||||||
{% endblock %}
|
|
||||||
{% block scripts %}
|
<style data-test-id="color-scheme">
|
||||||
{% endblock %}
|
@media (prefers-color-scheme: dark) {
|
||||||
</body>
|
:root {
|
||||||
|
color-scheme: dark light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style data-test-id="custom-branding-css">
|
||||||
|
{{ brand.branding_custom_css }}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="{% versioned_script 'dist/poly-%v.js' %}" type="module"></script>
|
||||||
|
<script
|
||||||
|
src="{% versioned_script 'dist/standalone/loading/index-%v.js' %}"
|
||||||
|
type="module"
|
||||||
|
></script>
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<meta name="sentry-trace" content="{{ sentry_trace }}" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
{% block scripts %}{% endblock %}
|
||||||
|
|
||||||
|
<noscript>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: var(--ak-font-family-base), sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
JavaScript is required to use
|
||||||
|
{% trans title|default:brand.branding_title %}
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
Please enable JavaScript in your browser settings and reload the page. If you are using a
|
||||||
|
browser extension that blocks JavaScript, please disable it for this site.
|
||||||
|
</p>
|
||||||
|
</noscript>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -4,14 +4,16 @@
|
|||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% versioned_script 'dist/admin/AdminInterface-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/admin/AdminInterface-%v.js' %}" type="module"></script>
|
||||||
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
|
|
||||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
|
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)" />
|
||||||
|
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
|
||||||
{% include "base/header_js.html" %}
|
{% include "base/header_js.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
|
|
||||||
<ak-interface-admin>
|
<ak-interface-admin>
|
||||||
<ak-loading></ak-loading>
|
<ak-loading></ak-loading>
|
||||||
</ak-interface-admin>
|
</ak-interface-admin>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -13,9 +13,14 @@
|
|||||||
|
|
||||||
{% block card %}
|
{% block card %}
|
||||||
<form method="POST" class="pf-c-form">
|
<form method="POST" class="pf-c-form">
|
||||||
<p>{% trans message %}</p>
|
<p>{% trans message %}</p>
|
||||||
<a id="ak-back-home" href="{% url 'authentik_core:root-redirect' %}" class="pf-c-button pf-m-primary">
|
|
||||||
{% trans 'Go home' %}
|
<a
|
||||||
</a>
|
id="ak-back-home"
|
||||||
|
href="{% url 'authentik_core:root-redirect' %}"
|
||||||
|
class="pf-c-button pf-m-primary"
|
||||||
|
>
|
||||||
|
{% trans 'Go home' %}
|
||||||
|
</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -4,14 +4,17 @@
|
|||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% versioned_script 'dist/user/UserInterface-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/user/UserInterface-%v.js' %}" type="module"></script>
|
||||||
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: light)">
|
|
||||||
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: dark)">
|
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: light)" />
|
||||||
|
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: dark)" />
|
||||||
|
|
||||||
{% include "base/header_js.html" %}
|
{% include "base/header_js.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
|
|
||||||
<ak-interface-user>
|
<ak-interface-user>
|
||||||
<ak-loading></ak-loading>
|
<ak-loading></ak-loading>
|
||||||
</ak-interface-user>
|
</ak-interface-user>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -5,78 +5,82 @@
|
|||||||
|
|
||||||
{% block head_before %}
|
{% block head_before %}
|
||||||
<link rel="prefetch" href="{{ request.brand.branding_default_flow_background_url }}" />
|
<link rel="prefetch" href="{{ request.brand.branding_default_flow_background_url }}" />
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly.min.css' %}">
|
<link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly.min.css' %}" />
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/theme-dark.css' %}" media="(prefers-color-scheme: dark)">
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="{% static 'dist/theme-dark.css' %}"
|
||||||
|
media="(prefers-color-scheme: dark)"
|
||||||
|
/>
|
||||||
{% include "base/header_js.html" %}
|
{% include "base/header_js.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<style>
|
<style data-test-id="base-full-root-styles">
|
||||||
:root {
|
:root {
|
||||||
--ak-flow-background: url("{{ request.brand.branding_default_flow_background_url }}");
|
--ak-flow-background: url("{{ request.brand.branding_default_flow_background_url }}");
|
||||||
--pf-c-background-image--BackgroundImage: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage: var(--ak-flow-background);
|
||||||
--pf-c-background-image--BackgroundImage-2x: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage-2x: var(--ak-flow-background);
|
||||||
--pf-c-background-image--BackgroundImage--sm: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage--sm: var(--ak-flow-background);
|
||||||
--pf-c-background-image--BackgroundImage--sm-2x: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage--sm-2x: var(--ak-flow-background);
|
||||||
--pf-c-background-image--BackgroundImage--lg: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage--lg: var(--ak-flow-background);
|
||||||
}
|
}
|
||||||
/* Form with user */
|
/* Form with user */
|
||||||
.form-control-static {
|
.form-control-static {
|
||||||
margin-top: var(--pf-global--spacer--sm);
|
margin-top: var(--pf-global--spacer--sm);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.form-control-static .avatar {
|
.form-control-static .avatar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.form-control-static img {
|
.form-control-static img {
|
||||||
margin-right: var(--pf-global--spacer--xs);
|
margin-right: var(--pf-global--spacer--xs);
|
||||||
}
|
}
|
||||||
.form-control-static a {
|
.form-control-static a {
|
||||||
padding-top: var(--pf-global--spacer--xs);
|
padding-top: var(--pf-global--spacer--xs);
|
||||||
padding-bottom: var(--pf-global--spacer--xs);
|
padding-bottom: var(--pf-global--spacer--xs);
|
||||||
line-height: var(--pf-global--spacer--xl);
|
line-height: var(--pf-global--spacer--xl);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="pf-c-background-image">
|
<div class="pf-c-background-image"></div>
|
||||||
</div>
|
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
<div class="pf-c-login stacked">
|
<div class="pf-c-login stacked">
|
||||||
<div class="ak-login-container">
|
<div class="ak-login-container">
|
||||||
<main class="pf-c-login__main">
|
<main class="pf-c-login__main">
|
||||||
<div class="pf-c-login__main-header pf-c-brand ak-brand">
|
<div class="pf-c-login__main-header pf-c-brand ak-brand">
|
||||||
<img src="{{ brand.branding_logo_url }}" alt="authentik Logo" />
|
<img src="{{ brand.branding_logo_url }}" alt="authentik Logo" />
|
||||||
</div>
|
</div>
|
||||||
<header class="pf-c-login__main-header">
|
<header class="pf-c-login__main-header">
|
||||||
<h1 class="pf-c-title pf-m-3xl">
|
<h1 class="pf-c-title pf-m-3xl">
|
||||||
{% block card_title %}
|
{% block card_title %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<div class="pf-c-login__main-body">
|
<div class="pf-c-login__main-body">
|
||||||
{% block card %}
|
{% block card %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<footer class="pf-c-login__footer">
|
<footer class="pf-c-login__footer">
|
||||||
<ul class="pf-c-list pf-m-inline">
|
<ul class="pf-c-list pf-m-inline">
|
||||||
{% for link in footer_links %}
|
{% for link in footer_links %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ link.href }}">{{ link.name }}</a>
|
<a href="{{ link.href }}">{{ link.name }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li>
|
<li>
|
||||||
<span>
|
<span>
|
||||||
{% trans 'Powered by authentik' %}
|
{% trans 'Powered by authentik' %}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -2,53 +2,52 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load authentik_core %}
|
{% load authentik_core %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||||
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
||||||
<link rel="icon" href="{{ brand.branding_favicon_url }}">
|
<link rel="icon" href="{{ brand.branding_favicon_url }}" />
|
||||||
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}">
|
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}" />
|
||||||
{% block head_before %}
|
{% block head_before %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/sfe/bootstrap.min.css' %}">
|
<link rel="stylesheet" type="text/css" href="{% static 'dist/sfe/bootstrap.min.css' %}" />
|
||||||
<meta name="sentry-trace" content="{{ sentry_trace }}" />
|
<meta name="sentry-trace" content="{{ sentry_trace }}" />
|
||||||
{% include "base/header_js.html" %}
|
{% include "base/header_js.html" %}
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
background-image: url("{{ flow.background_url }}");
|
background-image: url("{{ flow.background_url }}");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
.card {
|
.card {
|
||||||
padding: 3rem;
|
padding: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-signin {
|
.form-signin {
|
||||||
max-width: 330px;
|
max-width: 330px;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-signin .form-floating:focus-within {
|
.form-signin .form-floating:focus-within {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
.brand-icon {
|
.brand-icon {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
||||||
<div class="card m-auto">
|
<div class="card m-auto">
|
||||||
<main class="form-signin w-100 m-auto" id="flow-sfe-container">
|
<main class="form-signin w-100 m-auto" id="flow-sfe-container"></main>
|
||||||
</main>
|
<span class="mt-3 mb-0 text-muted text-center">{% trans 'Powered by authentik' %}</span>
|
||||||
<span class="mt-3 mb-0 text-muted text-center">{% trans 'Powered by authentik' %}</span>
|
</div>
|
||||||
</div>
|
<script src="{% static 'dist/sfe/index.js' %}"></script>
|
||||||
<script src="{% static 'dist/sfe/index.js' %}"></script>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,34 +1,40 @@
|
|||||||
{% extends "base/skeleton.html" %}
|
{% extends "base/skeleton.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load authentik_core %}
|
{% load authentik_core %}
|
||||||
|
|
||||||
{% block head_before %}
|
{% block head_before %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|
||||||
<link rel="prefetch" href="{{ flow.background_url }}" />
|
<link rel="prefetch" href="{{ flow.background_url }}" />
|
||||||
|
|
||||||
{% if flow.compatibility_mode and not inspector %}
|
{% if flow.compatibility_mode and not inspector %}
|
||||||
<script>ShadyDOM = { force: !navigator.webdriver };</script>
|
|
||||||
{% endif %}
|
|
||||||
{% include "base/header_js.html" %}
|
|
||||||
<script>
|
<script>
|
||||||
window.authentik.flow = {
|
ShadyDOM = { force: !navigator.webdriver };
|
||||||
"layout": "{{ flow.layout }}",
|
</script>
|
||||||
};
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "base/header_js.html" %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.authentik.flow = {
|
||||||
|
layout: "{{ flow.layout }}",
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% versioned_script 'dist/flow/FlowInterface-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/flow/FlowInterface-%v.js' %}" type="module"></script>
|
||||||
<style>
|
|
||||||
:root {
|
<style data-test-id="flow-root-styles">
|
||||||
|
:root {
|
||||||
--ak-flow-background: url("{{ flow.background_url }}");
|
--ak-flow-background: url("{{ flow.background_url }}");
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
<ak-flow-executor flowSlug="{{ flow.slug }}">
|
<ak-flow-executor flowSlug="{{ flow.slug }}">
|
||||||
<ak-loading></ak-loading>
|
<ak-loading></ak-loading>
|
||||||
</ak-flow-executor>
|
</ak-flow-executor>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% versioned_script 'dist/rac/index-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/rac/index-%v.js' %}" type="module"></script>
|
||||||
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
|
|
||||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
|
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)" />
|
||||||
<link rel="icon" href="{{ tenant.branding_favicon_url }}">
|
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
|
||||||
<link rel="shortcut icon" href="{{ tenant.branding_favicon_url }}">
|
|
||||||
|
<link rel="icon" href="{{ tenant.branding_favicon_url }}" />
|
||||||
|
<link rel="shortcut icon" href="{{ tenant.branding_favicon_url }}" />
|
||||||
|
|
||||||
{% include "base/header_js.html" %}
|
{% include "base/header_js.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
10
eslint.config.mjs
Normal file
10
eslint.config.mjs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { createESLintPackageConfig } from "@goauthentik/eslint-config";
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ESLint configuration for authentik's monorepo.
|
||||||
|
*/
|
||||||
|
const ESLintConfig = createESLintPackageConfig();
|
||||||
|
|
||||||
|
export default ESLintConfig;
|
@ -1,15 +1,34 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||||
|
|
||||||
<title>{{.Title}}</title>
|
<title>{{.Title}}</title>
|
||||||
<link rel="shortcut icon" type="image/png" href="/outpost.goauthentik.io/static/dist/assets/icons/icon.png">
|
|
||||||
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/patternfly.min.css">
|
<link
|
||||||
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/authentik.css">
|
rel="shortcut icon"
|
||||||
<link rel="prefetch" href="/outpost.goauthentik.io/static/dist/assets/images/flow_background.jpg" />
|
type="image/png"
|
||||||
<style>
|
href="/outpost.goauthentik.io/static/dist/assets/icons/icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="/outpost.goauthentik.io/static/dist/patternfly.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="/outpost.goauthentik.io/static/dist/authentik.css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="prefetch"
|
||||||
|
href="/outpost.goauthentik.io/static/dist/assets/images/flow_background.jpg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style data-test-id="outpost-error-root-styles">
|
||||||
.pf-c-background-image::before {
|
.pf-c-background-image::before {
|
||||||
--ak-flow-background: url("/outpost.goauthentik.io/static/dist/assets/images/flow_background.jpg");
|
--ak-flow-background: url("/outpost.goauthentik.io/static/dist/assets/images/flow_background.jpg");
|
||||||
}
|
}
|
||||||
@ -24,13 +43,15 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="pf-c-background-image">
|
<div class="pf-c-background-image"></div>
|
||||||
</div>
|
|
||||||
<div class="pf-c-login stacked">
|
<div class="pf-c-login stacked">
|
||||||
<div class="ak-login-container">
|
<div class="ak-login-container">
|
||||||
<main class="pf-c-login__main">
|
<main class="pf-c-login__main">
|
||||||
<div class="pf-c-login__main-header pf-c-brand ak-brand">
|
<div class="pf-c-login__main-header pf-c-brand ak-brand">
|
||||||
<img src="/outpost.goauthentik.io/static/dist/assets/icons/icon_left_brand.svg" alt="authentik Logo" />
|
<img
|
||||||
|
src="/outpost.goauthentik.io/static/dist/assets/icons/icon_left_brand.svg"
|
||||||
|
alt="authentik Logo"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<header class="pf-c-login__main-header">
|
<header class="pf-c-login__main-header">
|
||||||
<h1 class="pf-c-title pf-m-3xl">
|
<h1 class="pf-c-title pf-m-3xl">
|
||||||
@ -47,9 +68,7 @@
|
|||||||
<footer class="pf-c-login__footer">
|
<footer class="pf-c-login__footer">
|
||||||
<ul class="pf-c-list pf-m-inline">
|
<ul class="pf-c-list pf-m-inline">
|
||||||
<li>
|
<li>
|
||||||
<span>
|
<span> Powered by authentik </span>
|
||||||
Powered by authentik
|
|
||||||
</span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/lifecycle-aws",
|
"name": "@goauthentik/lifecycle-aws",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"aws-cfn": "cross-env CI=false cdk synth --version-reporting=false > template.yaml"
|
"aws-cfn": "cross-env CI=false cdk synth --version-reporting=false > template.yaml"
|
||||||
},
|
},
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"aws-cdk": "^2.1007.0",
|
"aws-cdk": "^2.1007.0",
|
||||||
"cross-env": "^7.0.3"
|
"cross-env": "^7.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44519
package-lock.json
generated
44519
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
@ -1,5 +1,50 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/authentik",
|
"name": "@goauthentik/universe",
|
||||||
"version": "2025.2.4",
|
"version": "2025.2.4",
|
||||||
"private": true
|
"description": "Monorepo for authentik.",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"lint": "run-s lint:prettier:check lint:eslint:check",
|
||||||
|
"lint:eslint:check": "eslint .",
|
||||||
|
"lint:eslint:fix": "eslint --fix .",
|
||||||
|
"lint:fix": "run-s lint:prettier:fix lint:eslint:fix",
|
||||||
|
"lint:prettier:check": "prettier --cache --check -u .",
|
||||||
|
"lint:prettier:fix": "prettier --cache --write -u .",
|
||||||
|
"typecheck": "NODE_OPTIONS=\"--max-old-space-size=3000\" tsc -b"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint/js": "^9.11.1",
|
||||||
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
|
"eslint": "^9.23.0",
|
||||||
|
"eslint-plugin-lit": "^2.0.0",
|
||||||
|
"eslint-plugin-wc": "^3.0.0",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"prettier": "^3.5.3",
|
||||||
|
"prettier-plugin-django-alpine": "^1.3.0",
|
||||||
|
"prettier-plugin-packagejson": "^2.5.10",
|
||||||
|
"typescript": "^5.8.2",
|
||||||
|
"typescript-eslint": "^8.29.0",
|
||||||
|
"zx": "^8.4.1"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@esbuild/darwin-arm64": "^0.24.0",
|
||||||
|
"@esbuild/linux-amd64": "^0.18.11",
|
||||||
|
"@esbuild/linux-arm64": "^0.24.0",
|
||||||
|
"@rollup/rollup-darwin-arm64": "4.23.0",
|
||||||
|
"@rollup/rollup-linux-arm64-gnu": "4.23.0",
|
||||||
|
"@rollup/rollup-linux-x64-gnu": "4.23.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.11"
|
||||||
|
},
|
||||||
|
"workspaces": [
|
||||||
|
"gen-ts-api",
|
||||||
|
"web",
|
||||||
|
"web/packages/*",
|
||||||
|
"website",
|
||||||
|
"packages/*"
|
||||||
|
],
|
||||||
|
"prettier": "@goauthentik/prettier-config"
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.badge--support-community {
|
.badge--support-community {
|
||||||
--ifm-badge-background-color: var(
|
--ifm-badge-background-color: var(--ifm-color-secondary-contrast-foreground);
|
||||||
--ifm-color-secondary-contrast-foreground
|
|
||||||
);
|
|
||||||
--ifm-badge-border-color: var(--ifm-color-secondary-dark);
|
--ifm-badge-border-color: var(--ifm-color-secondary-dark);
|
||||||
--ifm-badge-color: var(--ifm-color-secondary-contrast-background);
|
--ifm-badge-color: var(--ifm-color-secondary-contrast-background);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
:root {
|
:root {
|
||||||
--ifm-font-family-base:
|
--ifm-font-family-base:
|
||||||
RedHatVF, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell,
|
RedHatVF, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans,
|
||||||
Noto Sans, sans-serif, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial,
|
sans-serif, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif,
|
||||||
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
|
|
||||||
--ifm-font-family-monospace:
|
--ifm-font-family-monospace:
|
||||||
RedHatMonoVF, SFMono-Regular, Menlo, Monaco, Consolas,
|
RedHatMonoVF, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
||||||
"Liberation Mono", "Courier New", monospace;
|
monospace;
|
||||||
|
|
||||||
--ifm-heading-font-family: RedHatDisplayVF, var(--ifm-font-family-base);
|
--ifm-heading-font-family: RedHatDisplayVF, var(--ifm-font-family-base);
|
||||||
|
|
||||||
|
@ -7,11 +7,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.homepage_hero__subtitle p {
|
.homepage_hero__subtitle p {
|
||||||
font-size: clamp(
|
font-size: clamp(1.125rem, 0.9946rem + 0.6522vi, 1.5rem); /* Adjust font as page scales */
|
||||||
1.125rem,
|
|
||||||
0.9946rem + 0.6522vi,
|
|
||||||
1.5rem
|
|
||||||
); /* Adjust font as page scales */
|
|
||||||
max-width: 28ch; /* Apply a maximum to keep everything in the box */
|
max-width: 28ch; /* Apply a maximum to keep everything in the box */
|
||||||
text-wrap: balance; /* Prevent widows, orphans, and runts. Doesn't work in Safari */
|
text-wrap: balance; /* Prevent widows, orphans, and runts. Doesn't work in Safari */
|
||||||
}
|
}
|
||||||
|
@ -122,12 +122,8 @@
|
|||||||
|
|
||||||
@media (min-width: 999px) {
|
@media (min-width: 999px) {
|
||||||
border-inline-start: 1px solid var(--ifm-hover-overlay);
|
border-inline-start: 1px solid var(--ifm-hover-overlay);
|
||||||
margin-inline-start: calc(
|
margin-inline-start: calc(var(--ifm-navbar-item-padding-horizontal) / 2);
|
||||||
var(--ifm-navbar-item-padding-horizontal) / 2
|
padding-inline-start: calc(var(--ifm-navbar-item-padding-horizontal) / 2);
|
||||||
);
|
|
||||||
padding-inline-start: calc(
|
|
||||||
var(--ifm-navbar-item-padding-horizontal) / 2
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,19 +147,14 @@
|
|||||||
hsl(236.84deg 34.55% 10.78%)
|
hsl(236.84deg 34.55% 10.78%)
|
||||||
);
|
);
|
||||||
--docsearch-key-shadow:
|
--docsearch-key-shadow:
|
||||||
inset 0 -2px 0 0 hsl(233.33deg 36% 24.51%),
|
inset 0 -2px 0 0 hsl(233.33deg 36% 24.51%), inset 0 0 1px 1px hsl(232.11deg 34.86% 57.25%),
|
||||||
inset 0 0 1px 1px hsl(232.11deg 34.86% 57.25%),
|
|
||||||
0 2px 2px 0 rgba(3, 4, 9, 0.3);
|
0 2px 2px 0 rgba(3, 4, 9, 0.3);
|
||||||
--docsearch-key-pressed-shadow:
|
--docsearch-key-pressed-shadow:
|
||||||
inset 0 -2px 0 0 #282d55,
|
inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px hsl(231.82deg 21.36% 40.39%),
|
||||||
inset 0 0 1px 1px hsl(231.82deg 21.36% 40.39%),
|
|
||||||
0 1px 1px 0 hsl(230deg 50% 2.35% / 30.2%);
|
0 1px 1px 0 hsl(230deg 50% 2.35% / 30.2%);
|
||||||
|
|
||||||
padding: var(--ifm-navbar-item-padding-vertical)
|
padding: var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal) !important;
|
||||||
var(--ifm-navbar-item-padding-horizontal) !important;
|
padding-inline-end: calc(var(--ifm-navbar-item-padding-horizontal) * 1.25) !important;
|
||||||
padding-inline-end: calc(
|
|
||||||
var(--ifm-navbar-item-padding-horizontal) * 1.25
|
|
||||||
) !important;
|
|
||||||
|
|
||||||
.DocSearch-Button-Placeholder {
|
.DocSearch-Button-Placeholder {
|
||||||
font-family: var(--ifm-heading-font-family);
|
font-family: var(--ifm-heading-font-family);
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
* @import { Config as DocusaurusConfig } from "@docusaurus/types"
|
* @import { Config as DocusaurusConfig } from "@docusaurus/types"
|
||||||
* @import { UserThemeConfig } from "./theme.js"
|
* @import { UserThemeConfig } from "./theme.js"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { deepmerge } from "deepmerge-ts";
|
import { deepmerge } from "deepmerge-ts";
|
||||||
|
|
||||||
import { createThemeConfig } from "./theme.js";
|
import { createThemeConfig } from "./theme.js";
|
||||||
|
|
||||||
//#region Types
|
//#region Types
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
* @import { UserThemeConfig as UserThemeConfigCommon } from "@docusaurus/theme-common";
|
* @import { UserThemeConfig as UserThemeConfigCommon } from "@docusaurus/theme-common";
|
||||||
* @import { UserThemeConfig as UserThemeConfigAlgolia } from "@docusaurus/theme-search-algolia";
|
* @import { UserThemeConfig as UserThemeConfigAlgolia } from "@docusaurus/theme-search-algolia";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { deepmerge } from "deepmerge-ts";
|
import { deepmerge } from "deepmerge-ts";
|
||||||
import { themes as prismThemes } from "prism-react-renderer";
|
import { themes as prismThemes } from "prism-react-renderer";
|
||||||
|
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file Client-side observer for ESBuild events.
|
||||||
* Client-side observer for ESBuild events.
|
*
|
||||||
|
* @import { Message as ESBuildMessage } from "esbuild";
|
||||||
*/
|
*/
|
||||||
import type { Message as ESBuildMessage } from "esbuild";
|
|
||||||
|
|
||||||
const logPrefix = "👷 [ESBuild]";
|
const logPrefix = "👷 [ESBuild]";
|
||||||
const log = console.debug.bind(console, logPrefix);
|
const log = console.debug.bind(console, logPrefix);
|
||||||
|
|
||||||
type BuildEventListener<Data = unknown> = (event: MessageEvent<Data>) => void;
|
/**
|
||||||
|
* @template {unknown} [Data=unknown]
|
||||||
|
* @typedef {(event: MessageEvent) => void} BuildEventListener
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A client-side watcher for ESBuild.
|
* A client-side watcher for ESBuild.
|
||||||
@ -17,13 +20,11 @@ type BuildEventListener<Data = unknown> = (event: MessageEvent<Data>) => void;
|
|||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* if (process.env.NODE_ENV === "development" && process.env.WATCHER_URL) {
|
* if (process.env.NODE_ENV === "development" && process.env.WATCHER_URL) {
|
||||||
* const { ESBuildObserver } = await import("@goauthentik/common/client");
|
* const { ESBuildObserver } = await import("@goauthentik/esbuild-plugin-live-reload/client");
|
||||||
*
|
*
|
||||||
* new ESBuildObserver(process.env.WATCHER_URL);
|
* ESBuildObserver.initialize(process.env.WATCHER_URL);
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
export class ESBuildObserver extends EventSource {
|
export class ESBuildObserver extends EventSource {
|
||||||
/**
|
/**
|
||||||
@ -58,15 +59,19 @@ export class ESBuildObserver extends EventSource {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The interval for the keep-alive check.
|
* The interval for the keep-alive check.
|
||||||
|
* @type {ReturnType<typeof setInterval> | undefined}
|
||||||
*/
|
*/
|
||||||
#keepAliveInterval: ReturnType<typeof setInterval> | undefined;
|
#keepAliveInterval;
|
||||||
|
|
||||||
#trackActivity = () => {
|
#trackActivity = () => {
|
||||||
this.lastUpdatedAt = Date.now();
|
this.lastUpdatedAt = Date.now();
|
||||||
this.alive = true;
|
this.alive = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
#startListener: BuildEventListener = () => {
|
/**
|
||||||
|
* @type {BuildEventListener}
|
||||||
|
*/
|
||||||
|
#startListener = () => {
|
||||||
this.#trackActivity();
|
this.#trackActivity();
|
||||||
log("⏰ Build started...");
|
log("⏰ Build started...");
|
||||||
};
|
};
|
||||||
@ -82,13 +87,18 @@ export class ESBuildObserver extends EventSource {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#errorListener: BuildEventListener<string> = (event) => {
|
/**
|
||||||
|
* @type {BuildEventListener<string>}
|
||||||
|
*/
|
||||||
|
#errorListener = (event) => {
|
||||||
this.#trackActivity();
|
this.#trackActivity();
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.group(logPrefix, "⛔️⛔️⛔️ Build error...");
|
console.group(logPrefix, "⛔️⛔️⛔️ Build error...");
|
||||||
|
|
||||||
const esbuildErrorMessages: ESBuildMessage[] = JSON.parse(event.data);
|
/**
|
||||||
|
* @type {ESBuildMessage[]}
|
||||||
|
*/
|
||||||
|
const esbuildErrorMessages = JSON.parse(event.data);
|
||||||
|
|
||||||
for (const error of esbuildErrorMessages) {
|
for (const error of esbuildErrorMessages) {
|
||||||
console.warn(error.text);
|
console.warn(error.text);
|
||||||
@ -101,11 +111,13 @@ export class ESBuildObserver extends EventSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endListener: BuildEventListener = () => {
|
/**
|
||||||
|
* @type {BuildEventListener}
|
||||||
|
*/
|
||||||
|
#endListener = () => {
|
||||||
cancelAnimationFrame(this.#reloadFrameID);
|
cancelAnimationFrame(this.#reloadFrameID);
|
||||||
|
|
||||||
this.#trackActivity();
|
this.#trackActivity();
|
||||||
@ -126,12 +138,32 @@ export class ESBuildObserver extends EventSource {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
#keepAliveListener: BuildEventListener = () => {
|
/**
|
||||||
|
* @type {BuildEventListener}
|
||||||
|
*/
|
||||||
|
#keepAliveListener = () => {
|
||||||
this.#trackActivity();
|
this.#trackActivity();
|
||||||
log("🏓 Keep-alive");
|
log("🏓 Keep-alive");
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(url: string | URL) {
|
/**
|
||||||
|
* Initialize the ESBuild observer.
|
||||||
|
* This should be called once in your application.
|
||||||
|
*
|
||||||
|
* @param {string | URL} url
|
||||||
|
* @returns {ESBuildObserver}
|
||||||
|
*/
|
||||||
|
static initialize(url) {
|
||||||
|
const esbuildObserver = new ESBuildObserver(url);
|
||||||
|
|
||||||
|
return esbuildObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string | URL} url
|
||||||
|
*/
|
||||||
|
constructor(url) {
|
||||||
super(url);
|
super(url);
|
||||||
|
|
||||||
this.addEventListener("esbuild:start", this.#startListener);
|
this.addEventListener("esbuild:start", this.#startListener);
|
2
packages/esbuild-plugin-live-reload/index.js
Normal file
2
packages/esbuild-plugin-live-reload/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from "./client/index.js";
|
||||||
|
export * from "./plugin/index.js";
|
46
packages/esbuild-plugin-live-reload/package.json
Normal file
46
packages/esbuild-plugin-live-reload/package.json
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "@goauthentik/esbuild-plugin-live-reload",
|
||||||
|
"version": "1.0.4",
|
||||||
|
"description": "ESBuild plugin to watch for file changes and trigger client-side reloads.",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
"./package.json": "./package.json",
|
||||||
|
".": {
|
||||||
|
"import": "./index.js",
|
||||||
|
"types": "./out/index.d.ts"
|
||||||
|
},
|
||||||
|
"./client": {
|
||||||
|
"import": "./client/index.js",
|
||||||
|
"types": "./out/client/index.d.ts"
|
||||||
|
},
|
||||||
|
"./plugin": {
|
||||||
|
"import": "./plugin/index.js",
|
||||||
|
"types": "./out/plugin/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.14.1",
|
||||||
|
"esbuild": "^0.25.0",
|
||||||
|
"typescript": "^5.6.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"esbuild": "^0.25.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.11"
|
||||||
|
},
|
||||||
|
"types": "./out/index.d.ts",
|
||||||
|
"files": [
|
||||||
|
"./index.js",
|
||||||
|
"client/**/*",
|
||||||
|
"plugin/**/*",
|
||||||
|
"out/**/*"
|
||||||
|
],
|
||||||
|
"prettier": "@goauthentik/prettier-config",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
import * as http from "http";
|
/**
|
||||||
import path from "path";
|
* @file Live reload plugin for ESBuild.
|
||||||
|
*/
|
||||||
|
import * as http from "node:http";
|
||||||
|
import * as path from "node:path";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes a custom event to a text stream.
|
* Serializes a custom event to a text stream.
|
||||||
@ -22,7 +25,7 @@ export function serializeCustomEventToStream(event) {
|
|||||||
* @typedef {Object} BuildObserverOptions
|
* @typedef {Object} BuildObserverOptions
|
||||||
*
|
*
|
||||||
* @property {URL} serverURL
|
* @property {URL} serverURL
|
||||||
* @property {string} logPrefix
|
* @property {string} [logPrefix]
|
||||||
* @property {string} relativeRoot
|
* @property {string} relativeRoot
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -32,8 +35,11 @@ export function serializeCustomEventToStream(event) {
|
|||||||
* @param {BuildObserverOptions} options
|
* @param {BuildObserverOptions} options
|
||||||
* @returns {import('esbuild').Plugin}
|
* @returns {import('esbuild').Plugin}
|
||||||
*/
|
*/
|
||||||
export function buildObserverPlugin({ serverURL, logPrefix, relativeRoot }) {
|
export function liveReloadPlugin({ serverURL, logPrefix = "Build Observer", relativeRoot }) {
|
||||||
const timerLabel = `[${logPrefix}] Build`;
|
const timerLabel = `[${logPrefix}] 🏁`;
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
const log = console.log.bind(console, `[${logPrefix}]`);
|
||||||
|
|
||||||
const endpoint = serverURL.pathname;
|
const endpoint = serverURL.pathname;
|
||||||
const dispatcher = new EventTarget();
|
const dispatcher = new EventTarget();
|
||||||
|
|
||||||
@ -43,18 +49,18 @@ export function buildObserverPlugin({ serverURL, logPrefix, relativeRoot }) {
|
|||||||
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
||||||
|
|
||||||
if (req.url !== endpoint) {
|
if (req.url !== endpoint) {
|
||||||
console.log(`🚫 Invalid request to ${req.url}`);
|
log(`🚫 Invalid request to ${req.url}`);
|
||||||
res.writeHead(404);
|
res.writeHead(404);
|
||||||
res.end();
|
res.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("🔌 Client connected");
|
log("🔌 Client connected");
|
||||||
|
|
||||||
res.writeHead(200, {
|
res.writeHead(200, {
|
||||||
"Content-Type": "text/event-stream",
|
"Content-Type": "text/event-stream",
|
||||||
"Cache-Control": "no-cache",
|
"Cache-Control": "no-cache",
|
||||||
"Connection": "keep-alive",
|
Connection: "keep-alive",
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,7 +77,7 @@ export function buildObserverPlugin({ serverURL, logPrefix, relativeRoot }) {
|
|||||||
dispatcher.addEventListener("esbuild:end", listener);
|
dispatcher.addEventListener("esbuild:end", listener);
|
||||||
|
|
||||||
req.on("close", () => {
|
req.on("close", () => {
|
||||||
console.log("🔌 Client disconnected");
|
log("🔌 Client disconnected");
|
||||||
|
|
||||||
clearInterval(keepAliveInterval);
|
clearInterval(keepAliveInterval);
|
||||||
|
|
10
packages/esbuild-plugin-live-reload/tsconfig.json
Normal file
10
packages/esbuild-plugin-live-reload/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "@goauthentik/tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"checkJs": true,
|
||||||
|
"emitDeclarationOnly": true
|
||||||
|
}
|
||||||
|
}
|
@ -23,8 +23,9 @@ export const DefaultIgnorePatterns = [
|
|||||||
"**/out",
|
"**/out",
|
||||||
"**/dist",
|
"**/dist",
|
||||||
"**/.wireit",
|
"**/.wireit",
|
||||||
|
"**/.venv",
|
||||||
"website/build/**",
|
"website/build/**",
|
||||||
"website/.docusaurus/**",
|
"**/.docusaurus/**",
|
||||||
"**/node_modules",
|
"**/node_modules",
|
||||||
"**/coverage",
|
"**/coverage",
|
||||||
"**/storybook-static",
|
"**/storybook-static",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import tseslint from "typescript-eslint";
|
import tseslint from "typescript-eslint";
|
||||||
|
|
||||||
|
import NodeLintPlugin from "../plugins/node-lint.js";
|
||||||
|
|
||||||
const MAX_DEPTH = 4;
|
const MAX_DEPTH = 4;
|
||||||
const MAX_NESTED_CALLBACKS = 4;
|
const MAX_NESTED_CALLBACKS = 4;
|
||||||
const MAX_PARAMS = 5;
|
const MAX_PARAMS = 5;
|
||||||
@ -9,22 +11,29 @@ const MAX_PARAMS = 5;
|
|||||||
* ESLint configuration for JavaScript authentik projects.
|
* ESLint configuration for JavaScript authentik projects.
|
||||||
*/
|
*/
|
||||||
export const javaScriptConfig = tseslint.config({
|
export const javaScriptConfig = tseslint.config({
|
||||||
|
plugins: {
|
||||||
|
"node-lint": NodeLintPlugin,
|
||||||
|
},
|
||||||
|
files: ["**/*.{js,jsx,mjs,cjs}"],
|
||||||
rules: {
|
rules: {
|
||||||
|
"node-lint/no-unprefixed-imports": "warn",
|
||||||
// TODO: Clean up before enabling.
|
// TODO: Clean up before enabling.
|
||||||
"accessor-pairs": "off",
|
"accessor-pairs": "off",
|
||||||
"array-callback-return": "error",
|
"array-callback-return": "error",
|
||||||
"block-scoped-var": "error",
|
"block-scoped-var": "error",
|
||||||
"consistent-return": ["error", { treatUndefinedAsUnspecified: false }],
|
"consistent-return": "off",
|
||||||
|
// "consistent-return": ["error", { treatUndefinedAsUnspecified: false }],
|
||||||
"consistent-this": ["error", "that"],
|
"consistent-this": ["error", "that"],
|
||||||
"curly": "off",
|
curly: "off",
|
||||||
"dot-notation": [
|
// "dot-notation": [
|
||||||
"error",
|
// "error",
|
||||||
{
|
// {
|
||||||
allowKeywords: true,
|
// allowKeywords: true,
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
"eqeqeq": "error",
|
// "eqeqeq": "error",
|
||||||
"func-names": ["error", "as-needed"],
|
eqeqeq: "off",
|
||||||
|
// "func-names": ["error", "as-needed"],
|
||||||
"guard-for-in": "error",
|
"guard-for-in": "error",
|
||||||
"max-depth": ["error", MAX_DEPTH],
|
"max-depth": ["error", MAX_DEPTH],
|
||||||
"max-nested-callbacks": ["error", MAX_NESTED_CALLBACKS],
|
"max-nested-callbacks": ["error", MAX_NESTED_CALLBACKS],
|
||||||
@ -33,13 +42,13 @@ export const javaScriptConfig = tseslint.config({
|
|||||||
// "new-cap": "error",
|
// "new-cap": "error",
|
||||||
"no-alert": "error",
|
"no-alert": "error",
|
||||||
"no-array-constructor": "error",
|
"no-array-constructor": "error",
|
||||||
"no-bitwise": [
|
// "no-bitwise": [
|
||||||
"error",
|
// "error",
|
||||||
{
|
// {
|
||||||
allow: ["~"],
|
// allow: ["~"],
|
||||||
int32Hint: true,
|
// int32Hint: true,
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
"no-caller": "error",
|
"no-caller": "error",
|
||||||
"no-case-declarations": "error",
|
"no-case-declarations": "error",
|
||||||
"no-class-assign": "error",
|
"no-class-assign": "error",
|
||||||
@ -53,10 +62,10 @@ export const javaScriptConfig = tseslint.config({
|
|||||||
"no-dupe-args": "error",
|
"no-dupe-args": "error",
|
||||||
"no-dupe-keys": "error",
|
"no-dupe-keys": "error",
|
||||||
"no-duplicate-case": "error",
|
"no-duplicate-case": "error",
|
||||||
"no-else-return": "error",
|
// "no-else-return": "error",
|
||||||
"no-empty": "error",
|
"no-empty": "error",
|
||||||
"no-empty-character-class": "error",
|
"no-empty-character-class": "error",
|
||||||
"no-empty-function": ["error", { allow: ["constructors"] }],
|
// "no-empty-function": ["error", { allow: ["constructors"] }],
|
||||||
"no-labels": "error",
|
"no-labels": "error",
|
||||||
"no-eq-null": "error",
|
"no-eq-null": "error",
|
||||||
"no-eval": "error",
|
"no-eval": "error",
|
||||||
@ -68,7 +77,7 @@ export const javaScriptConfig = tseslint.config({
|
|||||||
"no-fallthrough": "error",
|
"no-fallthrough": "error",
|
||||||
"no-func-assign": "error",
|
"no-func-assign": "error",
|
||||||
"no-implied-eval": "error",
|
"no-implied-eval": "error",
|
||||||
"no-implicit-coercion": "error",
|
"no-implicit-coercion": ["error", { boolean: true, allow: ["!!"] }],
|
||||||
"no-implicit-globals": "error",
|
"no-implicit-globals": "error",
|
||||||
"no-inner-declarations": ["error", "functions"],
|
"no-inner-declarations": ["error", "functions"],
|
||||||
"no-invalid-regexp": "error",
|
"no-invalid-regexp": "error",
|
||||||
@ -76,18 +85,18 @@ export const javaScriptConfig = tseslint.config({
|
|||||||
"no-iterator": "error",
|
"no-iterator": "error",
|
||||||
"no-label-var": "error",
|
"no-label-var": "error",
|
||||||
"no-lone-blocks": "error",
|
"no-lone-blocks": "error",
|
||||||
"no-lonely-if": "error",
|
// "no-lonely-if": "error",
|
||||||
"no-loop-func": "error",
|
"no-loop-func": "error",
|
||||||
"no-multi-str": "error",
|
"no-multi-str": "error",
|
||||||
// TODO: Clean up before enabling.
|
// TODO: Clean up before enabling.
|
||||||
"no-negated-condition": "off",
|
"no-negated-condition": "off",
|
||||||
"no-new": "error",
|
"no-new": "off",
|
||||||
"no-new-func": "error",
|
"no-new-func": "error",
|
||||||
"no-new-wrappers": "error",
|
"no-new-wrappers": "error",
|
||||||
"no-obj-calls": "error",
|
"no-obj-calls": "error",
|
||||||
"no-octal": "error",
|
"no-octal": "error",
|
||||||
"no-octal-escape": "error",
|
"no-octal-escape": "error",
|
||||||
"no-param-reassign": ["error", { props: false }],
|
// "no-param-reassign": ["error", { props: false }],
|
||||||
"no-proto": "error",
|
"no-proto": "error",
|
||||||
"no-redeclare": "error",
|
"no-redeclare": "error",
|
||||||
"no-regex-spaces": "error",
|
"no-regex-spaces": "error",
|
||||||
@ -99,39 +108,58 @@ export const javaScriptConfig = tseslint.config({
|
|||||||
// TODO: Clean up before enabling.
|
// TODO: Clean up before enabling.
|
||||||
// "no-shadow": "error",
|
// "no-shadow": "error",
|
||||||
"no-shadow-restricted-names": "error",
|
"no-shadow-restricted-names": "error",
|
||||||
"no-sparse-arrays": "error",
|
// TODO: Clean up before enabling.
|
||||||
|
// "no-sparse-arrays": "error",
|
||||||
"no-this-before-super": "error",
|
"no-this-before-super": "error",
|
||||||
"no-throw-literal": "error",
|
// "no-throw-literal": "error",
|
||||||
"no-trailing-spaces": "off", // Handled by Prettier.
|
"no-trailing-spaces": "off", // Handled by Prettier.
|
||||||
"no-undef": "off",
|
"no-undef": "off",
|
||||||
"no-undef-init": "off",
|
"no-undef-init": "off",
|
||||||
"no-unexpected-multiline": "error",
|
"no-unexpected-multiline": "error",
|
||||||
"no-useless-constructor": "error",
|
// "no-useless-constructor": "error",
|
||||||
"no-unmodified-loop-condition": "error",
|
"no-unmodified-loop-condition": "error",
|
||||||
"no-unneeded-ternary": "error",
|
"no-unneeded-ternary": "error",
|
||||||
"no-unreachable": "error",
|
"no-unreachable": "error",
|
||||||
"no-unused-expressions": "error",
|
"no-unused-expressions": "error",
|
||||||
"no-unused-labels": "error",
|
"no-unused-labels": "error",
|
||||||
"no-use-before-define": "error",
|
// "no-use-before-define": "error",
|
||||||
"no-useless-call": "error",
|
"no-useless-call": "error",
|
||||||
"no-dupe-class-members": "error",
|
"no-dupe-class-members": "error",
|
||||||
"no-var": "error",
|
"no-var": "error",
|
||||||
"no-void": "error",
|
"no-void": "error",
|
||||||
"no-with": "error",
|
"no-with": "error",
|
||||||
"prefer-arrow-callback": "error",
|
// "prefer-arrow-callback": "error",
|
||||||
"prefer-const": "error",
|
"prefer-const": "warn",
|
||||||
"prefer-rest-params": "error",
|
"prefer-rest-params": "error",
|
||||||
"prefer-spread": "error",
|
"prefer-spread": "error",
|
||||||
"prefer-template": "error",
|
"prefer-template": "off",
|
||||||
"radix": "error",
|
radix: "error",
|
||||||
"require-yield": "error",
|
"require-yield": "error",
|
||||||
"strict": ["error", "global"],
|
strict: ["error", "global"],
|
||||||
"use-isnan": "error",
|
"use-isnan": "error",
|
||||||
"valid-typeof": "error",
|
"valid-typeof": "error",
|
||||||
"vars-on-top": "error",
|
"vars-on-top": "error",
|
||||||
"yoda": ["error", "never"],
|
yoda: ["error", "never"],
|
||||||
|
|
||||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
"no-console": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
allow: [
|
||||||
|
//---
|
||||||
|
"debug",
|
||||||
|
"warn",
|
||||||
|
"error",
|
||||||
|
"group",
|
||||||
|
"groupCollapsed",
|
||||||
|
"groupEnd",
|
||||||
|
"table",
|
||||||
|
"trace",
|
||||||
|
"time",
|
||||||
|
"timeEnd",
|
||||||
|
"timeStamp",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
// SonarJS is not yet compatible with ESLint 9. Commenting these out
|
// SonarJS is not yet compatible with ESLint 9. Commenting these out
|
||||||
// until it is.
|
// until it is.
|
||||||
// "sonarjs/cognitive-complexity": ["off", MAX_COGNITIVE_COMPLEXITY],
|
// "sonarjs/cognitive-complexity": ["off", MAX_COGNITIVE_COMPLEXITY],
|
||||||
|
2
packages/eslint-config/lib/react-config.js
vendored
2
packages/eslint-config/lib/react-config.js
vendored
@ -13,7 +13,7 @@ export const reactConfig = tseslint.config({
|
|||||||
},
|
},
|
||||||
|
|
||||||
plugins: {
|
plugins: {
|
||||||
"react": reactPlugin,
|
react: reactPlugin,
|
||||||
"react-hooks": hooksPlugin,
|
"react-hooks": hooksPlugin,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,25 +1,42 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import tseslint from "typescript-eslint";
|
import tseslint from "typescript-eslint";
|
||||||
|
|
||||||
|
import NodeLintPlugin from "../plugins/node-lint.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ESLint configuration for TypeScript authentik projects.
|
* ESLint configuration for TypeScript authentik projects.
|
||||||
*/
|
*/
|
||||||
export const typescriptConfig = tseslint.config({
|
export const typescriptConfig = tseslint.config({
|
||||||
|
plugins: {
|
||||||
|
"node-lint": NodeLintPlugin,
|
||||||
|
},
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
"@typescript-eslint/ban-ts-comment": [
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
"error",
|
// "@typescript-eslint/ban-ts-comment": [
|
||||||
{
|
// "error",
|
||||||
"ts-expect-error": "allow-with-description",
|
// {
|
||||||
"ts-ignore": true,
|
// "ts-expect-error": "allow-with-description",
|
||||||
"ts-nocheck": "allow-with-description",
|
// "ts-ignore": true,
|
||||||
"ts-check": false,
|
// "ts-nocheck": "allow-with-description",
|
||||||
"minimumDescriptionLength": 5,
|
// "ts-check": false,
|
||||||
},
|
// "minimumDescriptionLength": 5,
|
||||||
],
|
// },
|
||||||
|
// ],
|
||||||
|
"@typescript-eslint/no-explicit-any": "warn",
|
||||||
|
"no-unused-private-class-members": "warn",
|
||||||
"no-use-before-define": "off",
|
"no-use-before-define": "off",
|
||||||
"@typescript-eslint/no-use-before-define": "error",
|
// "@typescript-eslint/no-use-before-define": "error",
|
||||||
"no-invalid-this": "off",
|
"no-invalid-this": "off",
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/triple-slash-reference": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
path: "never",
|
||||||
|
types: "always",
|
||||||
|
lib: "always",
|
||||||
|
},
|
||||||
|
],
|
||||||
"@typescript-eslint/no-namespace": "off",
|
"@typescript-eslint/no-namespace": "off",
|
||||||
"@typescript-eslint/no-unused-vars": [
|
"@typescript-eslint/no-unused-vars": [
|
||||||
"warn",
|
"warn",
|
||||||
|
@ -6,26 +6,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p ."
|
"build": "tsc -p ."
|
||||||
},
|
},
|
||||||
|
"main": "./index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": "./index.js",
|
||||||
"./package.json": "./package.json",
|
|
||||||
".": {
|
|
||||||
"import": "./index.js",
|
|
||||||
"types": "./out/index.d.ts"
|
|
||||||
},
|
|
||||||
"./react-config": {
|
|
||||||
"import": "./lib/react-config.js",
|
|
||||||
"types": "./out/lib/react-config.d.ts"
|
|
||||||
},
|
|
||||||
"./javascript-config": {
|
|
||||||
"import": "./lib/javascript-config.js",
|
|
||||||
"types": "./out/lib/javascript-config.d.ts"
|
|
||||||
},
|
|
||||||
"./typescript-config": {
|
|
||||||
"import": "./lib/typescript-config.js",
|
|
||||||
"types": "./out/lib/typescript-config.d.ts"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint": "^9.23.0",
|
"eslint": "^9.23.0",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
@ -35,8 +18,8 @@
|
|||||||
"eslint-plugin-wc": "^2.1.1"
|
"eslint-plugin-wc": "^2.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@goauthentik/prettier-config": "^1.0.1",
|
"@goauthentik/prettier-config": "^1.0.4",
|
||||||
"@goauthentik/tsconfig": "^1.0.1",
|
"@goauthentik/tsconfig": "^1.0.4",
|
||||||
"@types/eslint": "^9.6.1",
|
"@types/eslint": "^9.6.1",
|
||||||
"typescript": "^5.8.2",
|
"typescript": "^5.8.2",
|
||||||
"typescript-eslint": "^8.29.0"
|
"typescript-eslint": "^8.29.0"
|
||||||
|
85
packages/eslint-config/plugins/node-lint.js
Normal file
85
packages/eslint-config/plugins/node-lint.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* @file ESLint rule to enforce the use of the `node:` prefix for Node.js built-in modules.
|
||||||
|
*
|
||||||
|
* @import { Rule, ESLint } from "eslint";
|
||||||
|
* @import { RuleTextEditor } from "@eslint/core";
|
||||||
|
*/
|
||||||
|
import { builtinModules } from "node:module";
|
||||||
|
|
||||||
|
const NODE_PROTOCOL_PREFIX = "node:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Map<string, string>}
|
||||||
|
*/
|
||||||
|
const NodeModulesIndex = new Map();
|
||||||
|
|
||||||
|
for (const moduleName of builtinModules) {
|
||||||
|
if (moduleName.startsWith("_")) continue;
|
||||||
|
if (moduleName.startsWith(NODE_PROTOCOL_PREFIX)) continue;
|
||||||
|
|
||||||
|
NodeModulesIndex.set(moduleName, `${NODE_PROTOCOL_PREFIX}${moduleName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Rule.RuleModule}
|
||||||
|
*/
|
||||||
|
const rule = {
|
||||||
|
meta: {
|
||||||
|
type: "problem",
|
||||||
|
fixable: "code",
|
||||||
|
hasSuggestions: true,
|
||||||
|
docs: {
|
||||||
|
description: "Enforce `node:` prefix for Node.js built-in modules.",
|
||||||
|
recommended: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create: (context) => {
|
||||||
|
/**
|
||||||
|
* @type {Rule.RuleListener}
|
||||||
|
*/
|
||||||
|
const ruleListener = {
|
||||||
|
ImportDeclaration({ source }) {
|
||||||
|
if (source.type !== "Literal" || typeof source.value !== "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleName = source.value;
|
||||||
|
|
||||||
|
const prefixedModuleName = NodeModulesIndex.get(moduleName);
|
||||||
|
|
||||||
|
if (!prefixedModuleName) return;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RuleTextEditor} editor
|
||||||
|
*/
|
||||||
|
const fix = (editor) =>
|
||||||
|
editor.replaceText(source, JSON.stringify(prefixedModuleName));
|
||||||
|
|
||||||
|
context.report({
|
||||||
|
node: source,
|
||||||
|
message: `Module "${moduleName}" must use the "node:" prefix.`,
|
||||||
|
fix,
|
||||||
|
suggest: [
|
||||||
|
{
|
||||||
|
fix,
|
||||||
|
desc: `Use "${prefixedModuleName}" instead.`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return ruleListener;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ESLint.Plugin}
|
||||||
|
*/
|
||||||
|
const NodeLintPlugin = {
|
||||||
|
rules: {
|
||||||
|
"no-unprefixed-imports": rule,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NodeLintPlugin;
|
25
packages/monorepo/build.js
Normal file
25
packages/monorepo/build.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* @file Utility functions for building and copying files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an object of environment variables, returns a new object with the same keys and values, but
|
||||||
|
* with the values serialized as strings.
|
||||||
|
* @template {string} K
|
||||||
|
*
|
||||||
|
* @param {Record<K, string | number | boolean | object>} input
|
||||||
|
* @returns {Record<`process.env.${K}`, string>}
|
||||||
|
*/
|
||||||
|
export function serializeEnvironmentVars(input) {
|
||||||
|
/**
|
||||||
|
* @type {Record<string, string>}
|
||||||
|
*/
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(input)) {
|
||||||
|
const namespaceKey = `process.env.${key}`;
|
||||||
|
env[namespaceKey] = JSON.stringify(value || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return /** @type {Record<string, string>} */ (env);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
export * from "./paths.js";
|
export * from "./paths.js";
|
||||||
export * from "./constants.js";
|
export * from "./constants.js";
|
||||||
|
export * from "./build.js";
|
||||||
export * from "./version.js";
|
export * from "./version.js";
|
||||||
export * from "./scripting.js";
|
export * from "./scripting.js";
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/monorepo",
|
"name": "@goauthentik/monorepo",
|
||||||
"version": "1.0.0",
|
"version": "1.0.4",
|
||||||
"description": "Utilities for the authentik monorepo.",
|
"description": "Utilities for the authentik monorepo.",
|
||||||
"private": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": "./index.js",
|
||||||
"./package.json": "./package.json",
|
|
||||||
".": {
|
|
||||||
"import": "./index.js",
|
|
||||||
"types": "./out/index.d.ts"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"types": "./out/index.d.ts",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.11"
|
"node": ">=20.11"
|
||||||
}
|
},
|
||||||
|
"types": "./out/index.d.ts"
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|||||||
import { dirname, join, resolve } from "node:path";
|
import { dirname, join, resolve } from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const relativeDirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {'~authentik'} MonoRepoRoot
|
* @typedef {'~authentik'} MonoRepoRoot
|
||||||
@ -11,7 +11,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|||||||
/**
|
/**
|
||||||
* The root of the authentik monorepo.
|
* The root of the authentik monorepo.
|
||||||
*/
|
*/
|
||||||
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (resolve(__dirname, "..", ".."));
|
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (resolve(relativeDirname, "..", ".."));
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export const AuthentikPrettierConfig = {
|
|||||||
jsxSingleQuote: false,
|
jsxSingleQuote: false,
|
||||||
printWidth: 100,
|
printWidth: 100,
|
||||||
proseWrap: "preserve",
|
proseWrap: "preserve",
|
||||||
quoteProps: "consistent",
|
quoteProps: "as-needed",
|
||||||
requirePragma: false,
|
requirePragma: false,
|
||||||
semi: true,
|
semi: true,
|
||||||
singleQuote: false,
|
singleQuote: false,
|
||||||
@ -31,8 +31,23 @@ export const AuthentikPrettierConfig = {
|
|||||||
trailingComma: "all",
|
trailingComma: "all",
|
||||||
useTabs: false,
|
useTabs: false,
|
||||||
vueIndentScriptAndStyle: false,
|
vueIndentScriptAndStyle: false,
|
||||||
plugins: ["prettier-plugin-packagejson", "@trivago/prettier-plugin-sort-imports"],
|
plugins: [
|
||||||
importOrder: ["^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
|
// ---
|
||||||
|
"prettier-plugin-packagejson",
|
||||||
|
"@trivago/prettier-plugin-sort-imports",
|
||||||
|
"prettier-plugin-django-alpine",
|
||||||
|
],
|
||||||
|
importOrder: [
|
||||||
|
// ---
|
||||||
|
// Lit Imports
|
||||||
|
"^(@?)lit(.*)$",
|
||||||
|
// CSS Imports
|
||||||
|
"\\.css$",
|
||||||
|
// API Imports
|
||||||
|
"^@goauthentik/api$",
|
||||||
|
// Relative Imports
|
||||||
|
"^[./]",
|
||||||
|
],
|
||||||
importOrderSeparation: true,
|
importOrderSeparation: true,
|
||||||
importOrderSortSpecifiers: true,
|
importOrderSortSpecifiers: true,
|
||||||
importOrderParserPlugins: ["typescript", "jsx", "classProperties", "decorators-legacy"],
|
importOrderParserPlugins: ["typescript", "jsx", "classProperties", "decorators-legacy"],
|
||||||
@ -49,6 +64,13 @@ export const AuthentikPrettierConfig = {
|
|||||||
trailingComma: "none",
|
trailingComma: "none",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
files: "authentik/**/*.html",
|
||||||
|
options: {
|
||||||
|
tabWidth: 2,
|
||||||
|
parser: "html",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
files: "package.json",
|
files: "package.json",
|
||||||
options: {
|
options: {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p ."
|
"build": "tsc -p ."
|
||||||
},
|
},
|
||||||
|
"main": "./index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
"./package.json": "./package.json",
|
"./package.json": "./package.json",
|
||||||
@ -15,17 +16,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@goauthentik/tsconfig": "^1.0.1",
|
"@goauthentik/tsconfig": "^1.0.4",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-organize-imports": "^4.1.0",
|
"prettier-plugin-django-alpine": "^1.3.0",
|
||||||
"prettier-plugin-packagejson": "^2.5.10",
|
"prettier-plugin-packagejson": "^2.5.10",
|
||||||
"typescript": "^5.8.2"
|
"typescript": "^5.8.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-organize-imports": "^4.1.0",
|
"prettier-plugin-django-alpine": "^1.3.0",
|
||||||
"prettier-plugin-packagejson": "^2.5.10"
|
"prettier-plugin-packagejson": "^2.5.10"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -2,19 +2,16 @@
|
|||||||
"name": "@goauthentik/tsconfig",
|
"name": "@goauthentik/tsconfig",
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"description": "authentik's base TypeScript configuration.",
|
"description": "authentik's base TypeScript configuration.",
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "tsconfig.json",
|
||||||
|
"type": "module",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.11"
|
||||||
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tsconfig",
|
"tsconfig",
|
||||||
"typescript"
|
"typescript"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
|
||||||
"scripts": {
|
|
||||||
"build": ""
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"main": "tsconfig.json",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.11"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,14 @@ FROM --platform=${BUILDPLATFORM} docker.io/library/node:22 AS web-builder
|
|||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
WORKDIR /static
|
WORKDIR /static
|
||||||
|
|
||||||
COPY package.json /
|
COPY ./package.json ./package.json
|
||||||
RUN --mount=type=bind,target=/static/package.json,src=./web/package.json \
|
COPY ./package-lock.json ./package-lock.json
|
||||||
--mount=type=bind,target=/static/package-lock.json,src=./web/package-lock.json \
|
COPY ./packages ./packages
|
||||||
--mount=type=bind,target=/static/scripts,src=./web/scripts \
|
COPY ./web ./web
|
||||||
--mount=type=cache,target=/root/.npm \
|
|
||||||
npm ci --include=dev
|
RUN --mount=type=cache,target=/root/.npm npm ci --include=dev
|
||||||
|
RUN npm run build-proxy -w @goauthentik/web
|
||||||
|
|
||||||
COPY web .
|
|
||||||
RUN npm run build-proxy
|
|
||||||
|
|
||||||
# Stage 2: Build
|
# Stage 2: Build
|
||||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS builder
|
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS builder
|
||||||
@ -65,10 +64,10 @@ RUN apt-get update && \
|
|||||||
rm -rf /tmp/* /var/lib/apt/lists/*
|
rm -rf /tmp/* /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY --from=builder /go/proxy /
|
COPY --from=builder /go/proxy /
|
||||||
COPY --from=web-builder /static/robots.txt /web/robots.txt
|
COPY --from=web-builder /static/web/robots.txt /web/robots.txt
|
||||||
COPY --from=web-builder /static/security.txt /web/security.txt
|
COPY --from=web-builder /static/web/security.txt /web/security.txt
|
||||||
COPY --from=web-builder /static/dist/ /web/dist/
|
COPY --from=web-builder /static/web/dist/ /web/dist/
|
||||||
COPY --from=web-builder /static/authentik/ /web/authentik/
|
COPY --from=web-builder /static/web/authentik/ /web/authentik/
|
||||||
|
|
||||||
HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/proxy", "healthcheck" ]
|
HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/proxy", "healthcheck" ]
|
||||||
|
|
||||||
|
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// TypeScript Project Configuration
|
||||||
|
{
|
||||||
|
"watchOptions": {
|
||||||
|
"excludeDirectories": [
|
||||||
|
"**/.git", // Git
|
||||||
|
"**/.yarn", // Yarn
|
||||||
|
"**/.vscode", // VS Code
|
||||||
|
"**/.vscode-test-web", // VS Code Web Test
|
||||||
|
"**/dist", // Distributed build files
|
||||||
|
"**/out", // Output build files
|
||||||
|
"**/.drafts", // Drafts
|
||||||
|
"**/.github", // GitHub
|
||||||
|
"**/node_modules" // Node modules
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// The root project has no sources of its own. By setting `files` to an empty
|
||||||
|
// list, TS won't automatically include all sources below root (the default).
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
// Note that references are in the order we want them to be built.
|
||||||
|
{ "path": "./packages/prettier-config" },
|
||||||
|
{ "path": "./packages/eslint-config" },
|
||||||
|
{ "path": "./packages/esbuild-plugin-live-reload" },
|
||||||
|
{ "path": "./web" }
|
||||||
|
]
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
# don't ever lint node_modules
|
|
||||||
node_modules
|
|
||||||
# don't lint build output (make sure it's set to your correct build folder name)
|
|
||||||
dist
|
|
||||||
# don't lint nyc coverage output
|
|
||||||
coverage
|
|
||||||
# Import order matters
|
|
||||||
poly.ts
|
|
||||||
src/locale-codes.ts
|
|
||||||
src/locales/
|
|
||||||
storybook-static/
|
|
||||||
# Prettier breaks the tsconfig file
|
|
||||||
tsconfig.json
|
|
||||||
.storybook/css-import-maps*
|
|
||||||
package.json
|
|
||||||
packages/**/package.json
|
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"arrowParens": "always",
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"embeddedLanguageFormatting": "auto",
|
|
||||||
"htmlWhitespaceSensitivity": "css",
|
|
||||||
"insertPragma": false,
|
|
||||||
"jsxSingleQuote": false,
|
|
||||||
"printWidth": 100,
|
|
||||||
"proseWrap": "preserve",
|
|
||||||
"quoteProps": "consistent",
|
|
||||||
"requirePragma": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": false,
|
|
||||||
"tabWidth": 4,
|
|
||||||
"trailingComma": "all",
|
|
||||||
"useTabs": false,
|
|
||||||
"vueIndentScriptAndStyle": false,
|
|
||||||
"plugins": ["@trivago/prettier-plugin-sort-imports"],
|
|
||||||
"importOrder": ["^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
|
|
||||||
"importOrderSeparation": true,
|
|
||||||
"importOrderSortSpecifiers": true,
|
|
||||||
"importOrderParserPlugins": ["typescript", "jsx", "classProperties", "decorators-legacy"]
|
|
||||||
}
|
|
@ -1,14 +1,15 @@
|
|||||||
import replace from "@rollup/plugin-replace";
|
import { NodeEnvironment, resolvePackage, serializeEnvironmentVars } from "@goauthentik/monorepo";
|
||||||
|
import { PackageRoot } from "@goauthentik/web/paths";
|
||||||
import type { StorybookConfig } from "@storybook/web-components-vite";
|
import type { StorybookConfig } from "@storybook/web-components-vite";
|
||||||
import { cwd } from "process";
|
import { deepmerge } from "deepmerge-ts";
|
||||||
|
import * as path from "node:path";
|
||||||
import modify from "rollup-plugin-modify";
|
import modify from "rollup-plugin-modify";
|
||||||
import postcssLit from "rollup-plugin-postcss-lit";
|
import postcssLit from "rollup-plugin-postcss-lit";
|
||||||
import tsconfigPaths from "vite-tsconfig-paths";
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
|
||||||
export const isProdBuild = process.env.NODE_ENV === "production";
|
const AK_API_BASE_PATH = process.env.AK_API_BASE_PATH || "";
|
||||||
export const apiBasePath = process.env.AK_API_BASE_PATH || "";
|
|
||||||
|
|
||||||
const importInlinePatterns = [
|
const inlineImportPatterns = [
|
||||||
'import AKGlobal from "(\\.\\./)*common/styles/authentik\\.css',
|
'import AKGlobal from "(\\.\\./)*common/styles/authentik\\.css',
|
||||||
'import AKGlobal from "@goauthentik/common/styles/authentik\\.css',
|
'import AKGlobal from "@goauthentik/common/styles/authentik\\.css',
|
||||||
'import PF.+ from "@patternfly/patternfly/\\S+\\.css',
|
'import PF.+ from "@patternfly/patternfly/\\S+\\.css',
|
||||||
@ -17,7 +18,9 @@ const importInlinePatterns = [
|
|||||||
'import styles from "\\./LibraryPageImpl\\.css',
|
'import styles from "\\./LibraryPageImpl\\.css',
|
||||||
];
|
];
|
||||||
|
|
||||||
const importInlineRegexp = new RegExp(importInlinePatterns.map((a) => `(${a})`).join("|"));
|
const inlineImportPattern = new RegExp(inlineImportPatterns.map((a) => `(${a})`).join("|"));
|
||||||
|
|
||||||
|
const patternflyPath = resolvePackage("@patternfly/patternfly");
|
||||||
|
|
||||||
const config: StorybookConfig = {
|
const config: StorybookConfig = {
|
||||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||||
@ -29,19 +32,19 @@ const config: StorybookConfig = {
|
|||||||
],
|
],
|
||||||
staticDirs: [
|
staticDirs: [
|
||||||
{
|
{
|
||||||
from: "../node_modules/@patternfly/patternfly/patternfly-base.css",
|
from: path.resolve(patternflyPath, "patternfly-base.css"),
|
||||||
to: "@patternfly/patternfly/patternfly-base.css",
|
to: "@patternfly/patternfly/patternfly-base.css",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: "../src/common/styles/authentik.css",
|
from: path.resolve(PackageRoot, "src", "common", "styles", "authentik.css"),
|
||||||
to: "@goauthentik/common/styles/authentik.css",
|
to: "@goauthentik/common/styles/authentik.css",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: "../src/common/styles/theme-dark.css",
|
from: path.resolve(PackageRoot, "src", "common", "styles", "theme-dark.css"),
|
||||||
to: "@goauthentik/common/styles/theme-dark.css",
|
to: "@goauthentik/common/styles/theme-dark.css",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: "../src/common/styles/one-dark.css",
|
from: path.resolve(PackageRoot, "src", "common", "styles", "one-dark.css"),
|
||||||
to: "@goauthentik/common/styles/one-dark.css",
|
to: "@goauthentik/common/styles/one-dark.css",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -53,28 +56,25 @@ const config: StorybookConfig = {
|
|||||||
autodocs: "tag",
|
autodocs: "tag",
|
||||||
},
|
},
|
||||||
async viteFinal(config) {
|
async viteFinal(config) {
|
||||||
return {
|
return deepmerge(config, {
|
||||||
...config,
|
define: serializeEnvironmentVars({
|
||||||
|
NODE_ENV: NodeEnvironment,
|
||||||
|
CWD: process.cwd(),
|
||||||
|
AK_API_BASE_PATH: AK_API_BASE_PATH,
|
||||||
|
WATCHER_URL: "",
|
||||||
|
}),
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
modify({
|
modify({
|
||||||
find: importInlineRegexp,
|
find: inlineImportPattern,
|
||||||
replace: (match: RegExpMatchArray) => {
|
replace: (match: RegExpMatchArray) => {
|
||||||
return `${match}?inline`;
|
return `${match}?inline`;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
replace({
|
|
||||||
"process.env.NODE_ENV": JSON.stringify(
|
|
||||||
isProdBuild ? "production" : "development",
|
|
||||||
),
|
|
||||||
"process.env.CWD": JSON.stringify(cwd()),
|
|
||||||
"process.env.AK_API_BASE_PATH": JSON.stringify(apiBasePath),
|
|
||||||
"preventAssignment": true,
|
|
||||||
}),
|
|
||||||
...config.plugins,
|
|
||||||
postcssLit(),
|
postcssLit(),
|
||||||
tsconfigPaths(),
|
tsconfigPaths(),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<link rel="stylesheet" href="@patternfly/patternfly/patternfly-base.css" />
|
<link rel="stylesheet" href="@patternfly/patternfly/patternfly-base.css" />
|
||||||
<link rel="stylesheet" href="@goauthentik/common/styles/authentik.css" />
|
<link rel="stylesheet" href="@goauthentik/common/styles/authentik.css" />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
import eslint from "@eslint/js";
|
|
||||||
import tsparser from "@typescript-eslint/parser";
|
|
||||||
import litconf from "eslint-plugin-lit";
|
|
||||||
import wcconf from "eslint-plugin-wc";
|
|
||||||
import globals from "globals";
|
|
||||||
import tseslint from "typescript-eslint";
|
|
||||||
|
|
||||||
export default [
|
|
||||||
// You would not believe how much this change has frustrated users: ["if an ignores key is used
|
|
||||||
// without any other keys in the configuration object, then the patterns act as global
|
|
||||||
// ignores"](https://eslint.org/docs/latest/use/configure/ignore)
|
|
||||||
{
|
|
||||||
ignores: [
|
|
||||||
"dist/",
|
|
||||||
// don't lint the cache
|
|
||||||
".wireit/",
|
|
||||||
// let packages have their own configurations
|
|
||||||
"packages/",
|
|
||||||
// don't ever lint node_modules
|
|
||||||
"node_modules/",
|
|
||||||
".storybook/*",
|
|
||||||
// don't lint build output (make sure it's set to your correct build folder name)
|
|
||||||
// don't lint nyc coverage output
|
|
||||||
"coverage/",
|
|
||||||
"src/locale-codes.ts",
|
|
||||||
"storybook-static/",
|
|
||||||
"src/locales/",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
eslint.configs.recommended,
|
|
||||||
wcconf.configs["flat/recommended"],
|
|
||||||
litconf.configs["flat/recommended"],
|
|
||||||
...tseslint.configs.recommended,
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["src/**"],
|
|
||||||
rules: {
|
|
||||||
"lit/attribute-names": "off",
|
|
||||||
// "lit/attribute-names": "error",
|
|
||||||
"lit/no-private-properties": "error",
|
|
||||||
// "lit/prefer-nothing": "warn",
|
|
||||||
"lit/no-template-bind": "error",
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
argsIgnorePattern: "^_",
|
|
||||||
varsIgnorePattern: "^_",
|
|
||||||
caughtErrorsIgnorePattern: "^_",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
...globals.nodeBuiltin,
|
|
||||||
...globals.node,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["scripts/**/*.mjs", "*.ts", "*.mjs"],
|
|
||||||
rules: {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
// We WANT our scripts to output to the console!
|
|
||||||
"no-console": "off",
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
argsIgnorePattern: "^_",
|
|
||||||
varsIgnorePattern: "^_",
|
|
||||||
caughtErrorsIgnorePattern: "^_",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
26423
web/package-lock.json
generated
26423
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
156
web/package.json
156
web/package.json
@ -1,13 +1,39 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/web",
|
"name": "@goauthentik/web",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"overrides": {
|
"license": "MIT",
|
||||||
"rapidoc": {
|
"private": true,
|
||||||
"@apitools/openapi-parser@": "0.0.37"
|
"scripts": {
|
||||||
},
|
"build": "wireit",
|
||||||
"chromedriver": {
|
"build-locales": "wireit",
|
||||||
"axios": "^1.8.4"
|
"build-locales:build": "wireit",
|
||||||
}
|
"build-proxy": "wireit",
|
||||||
|
"build:sfe": "wireit",
|
||||||
|
"esbuild:watch": "node scripts/build-web.mjs --watch",
|
||||||
|
"extract-locales": "wireit",
|
||||||
|
"format": "wireit",
|
||||||
|
"lint": "wireit",
|
||||||
|
"lint:imports": "wireit",
|
||||||
|
"lint:lockfile": "wireit",
|
||||||
|
"lit-analyse": "wireit",
|
||||||
|
"postinstall": "bash scripts/patch-spotlight.sh",
|
||||||
|
"precommit": "wireit",
|
||||||
|
"prettier": "wireit",
|
||||||
|
"prettier-check": "wireit",
|
||||||
|
"pseudolocalize": "wireit",
|
||||||
|
"storybook": "storybook dev -p 6006",
|
||||||
|
"storybook:build": "wireit",
|
||||||
|
"test": "wireit",
|
||||||
|
"test:e2e": "wireit",
|
||||||
|
"test:e2e:watch": "wireit",
|
||||||
|
"test:watch": "wireit",
|
||||||
|
"watch": "run-s build-locales esbuild:watch"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
"./package.json": "./package.json",
|
||||||
|
"./paths": "./paths.js",
|
||||||
|
"./scripts/*": "./scripts/*.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-css": "^6.3.1",
|
"@codemirror/lang-css": "^6.3.1",
|
||||||
@ -44,6 +70,7 @@
|
|||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"deepmerge-ts": "^7.1.5",
|
"deepmerge-ts": "^7.1.5",
|
||||||
"dompurify": "^3.2.4",
|
"dompurify": "^3.2.4",
|
||||||
|
"esbuild-plugin-copy": "^2.1.1",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"guacamole-common-js": "^1.5.0",
|
"guacamole-common-js": "^1.5.0",
|
||||||
"hastscript": "^9.0.1",
|
"hastscript": "^9.0.1",
|
||||||
@ -62,6 +89,7 @@
|
|||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"remark-mdx-frontmatter": "^5.0.0",
|
"remark-mdx-frontmatter": "^5.0.0",
|
||||||
"style-mod": "^4.1.2",
|
"style-mod": "^4.1.2",
|
||||||
|
"trusted-types": "^2.0.0",
|
||||||
"ts-pattern": "^5.4.0",
|
"ts-pattern": "^5.4.0",
|
||||||
"unist-util-visit": "^5.0.0",
|
"unist-util-visit": "^5.0.0",
|
||||||
"webcomponent-qr-code": "^1.2.0",
|
"webcomponent-qr-code": "^1.2.0",
|
||||||
@ -69,12 +97,15 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.11.1",
|
"@eslint/js": "^9.11.1",
|
||||||
|
"@goauthentik/esbuild-plugin-live-reload": "^1.0.4",
|
||||||
|
"@goauthentik/monorepo": "^1.0.4",
|
||||||
|
"@goauthentik/prettier-config": "^1.0.4",
|
||||||
|
"@goauthentik/tsconfig": "^1.0.4",
|
||||||
"@hcaptcha/types": "^1.0.4",
|
"@hcaptcha/types": "^1.0.4",
|
||||||
"@lit/localize-tools": "^0.8.0",
|
"@lit/localize-tools": "^0.8.0",
|
||||||
"@rollup/plugin-replace": "^6.0.1",
|
"@rollup/plugin-replace": "^6.0.1",
|
||||||
"@storybook/addon-essentials": "^8.3.4",
|
"@storybook/addon-essentials": "^8.3.4",
|
||||||
"@storybook/addon-links": "^8.3.4",
|
"@storybook/addon-links": "^8.3.4",
|
||||||
"@storybook/api": "^7.6.17",
|
|
||||||
"@storybook/blocks": "^8.3.4",
|
"@storybook/blocks": "^8.3.4",
|
||||||
"@storybook/builder-vite": "^8.3.4",
|
"@storybook/builder-vite": "^8.3.4",
|
||||||
"@storybook/manager-api": "^8.3.4",
|
"@storybook/manager-api": "^8.3.4",
|
||||||
@ -84,13 +115,13 @@
|
|||||||
"@types/chart.js": "^2.9.41",
|
"@types/chart.js": "^2.9.41",
|
||||||
"@types/codemirror": "^5.60.15",
|
"@types/codemirror": "^5.60.15",
|
||||||
"@types/dompurify": "^3.0.5",
|
"@types/dompurify": "^3.0.5",
|
||||||
"@types/eslint__js": "^8.42.3",
|
|
||||||
"@types/grecaptcha": "^3.0.9",
|
"@types/grecaptcha": "^3.0.9",
|
||||||
"@types/guacamole-common-js": "^1.5.2",
|
"@types/guacamole-common-js": "^1.5.2",
|
||||||
"@types/mocha": "^10.0.8",
|
"@types/mocha": "^10.0.8",
|
||||||
"@types/node": "^22.7.4",
|
"@types/node": "^22.14.1",
|
||||||
"@types/react": "^18.3.13",
|
"@types/react": "^18.3.13",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
|
"@types/trusted-types": "^2.0.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
||||||
"@typescript-eslint/parser": "^8.8.0",
|
"@typescript-eslint/parser": "^8.8.0",
|
||||||
"@wdio/browser-runner": "9.4",
|
"@wdio/browser-runner": "9.4",
|
||||||
@ -105,18 +136,15 @@
|
|||||||
"eslint-plugin-wc": "^2.1.1",
|
"eslint-plugin-wc": "^2.1.1",
|
||||||
"find-free-ports": "^3.1.1",
|
"find-free-ports": "^3.1.1",
|
||||||
"github-slugger": "^2.0.0",
|
"github-slugger": "^2.0.0",
|
||||||
"glob": "^11.0.0",
|
|
||||||
"globals": "^15.10.0",
|
|
||||||
"knip": "^5.30.6",
|
"knip": "^5.30.6",
|
||||||
"lit-analyzer": "^2.0.3",
|
"lit-analyzer": "^2.0.3",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.5.3",
|
||||||
"pseudolocale": "^2.1.0",
|
"pseudolocale": "^2.1.0",
|
||||||
"rollup-plugin-modify": "^3.0.0",
|
"rollup-plugin-modify": "^3.0.0",
|
||||||
"rollup-plugin-postcss-lit": "^2.1.0",
|
"rollup-plugin-postcss-lit": "^2.1.0",
|
||||||
"storybook": "^8.3.4",
|
"storybook": "^8.3.4",
|
||||||
"storybook-addon-mock": "^5.0.0",
|
"storybook-addon-mock": "^5.0.0",
|
||||||
"syncpack": "^13.0.0",
|
|
||||||
"turnstile-types": "^1.2.3",
|
"turnstile-types": "^1.2.3",
|
||||||
"typescript": "^5.6.2",
|
"typescript": "^5.6.2",
|
||||||
"typescript-eslint": "^8.8.0",
|
"typescript-eslint": "^8.8.0",
|
||||||
@ -124,10 +152,6 @@
|
|||||||
"vite-tsconfig-paths": "^5.0.1",
|
"vite-tsconfig-paths": "^5.0.1",
|
||||||
"wireit": "^0.14.9"
|
"wireit": "^0.14.9"
|
||||||
},
|
},
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@esbuild/darwin-arm64": "^0.24.0",
|
"@esbuild/darwin-arm64": "^0.24.0",
|
||||||
"@esbuild/linux-amd64": "^0.18.11",
|
"@esbuild/linux-amd64": "^0.18.11",
|
||||||
@ -136,39 +160,6 @@
|
|||||||
"@rollup/rollup-linux-arm64-gnu": "4.23.0",
|
"@rollup/rollup-linux-arm64-gnu": "4.23.0",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.23.0"
|
"@rollup/rollup-linux-x64-gnu": "4.23.0"
|
||||||
},
|
},
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"build": "wireit",
|
|
||||||
"build-locales": "wireit",
|
|
||||||
"build-locales:build": "wireit",
|
|
||||||
"build-proxy": "wireit",
|
|
||||||
"build:sfe": "wireit",
|
|
||||||
"esbuild:watch": "node scripts/build-web.mjs --watch",
|
|
||||||
"extract-locales": "wireit",
|
|
||||||
"format": "wireit",
|
|
||||||
"lint": "wireit",
|
|
||||||
"lint:imports": "wireit",
|
|
||||||
"lint:lockfile": "wireit",
|
|
||||||
"lint:nightmare": "wireit",
|
|
||||||
"lint:package": "wireit",
|
|
||||||
"lint:precommit": "wireit",
|
|
||||||
"lint:types": "wireit",
|
|
||||||
"lit-analyse": "wireit",
|
|
||||||
"postinstall": "bash scripts/patch-spotlight.sh",
|
|
||||||
"precommit": "wireit",
|
|
||||||
"prettier": "wireit",
|
|
||||||
"prettier-check": "wireit",
|
|
||||||
"pseudolocalize": "wireit",
|
|
||||||
"storybook": "storybook dev -p 6006",
|
|
||||||
"storybook:build": "wireit",
|
|
||||||
"test": "wireit",
|
|
||||||
"test:e2e": "wireit",
|
|
||||||
"test:e2e:watch": "wireit",
|
|
||||||
"test:watch": "wireit",
|
|
||||||
"tsc": "wireit",
|
|
||||||
"watch": "run-s build-locales esbuild:watch"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"wireit": {
|
"wireit": {
|
||||||
"build": {
|
"build": {
|
||||||
"#comment": [
|
"#comment": [
|
||||||
@ -245,10 +236,7 @@
|
|||||||
"command": "lit-localize extract"
|
"command": "lit-localize extract"
|
||||||
},
|
},
|
||||||
"format": {
|
"format": {
|
||||||
"command": "prettier --write .",
|
"command": "prettier --write ."
|
||||||
"dependencies": [
|
|
||||||
"lint:package"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"format:packages": {
|
"format:packages": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -267,16 +255,6 @@
|
|||||||
"lint:imports": {
|
"lint:imports": {
|
||||||
"command": "knip --config scripts/knip.config.ts"
|
"command": "knip --config scripts/knip.config.ts"
|
||||||
},
|
},
|
||||||
"lint:types:tests": {
|
|
||||||
"command": "tsc --noEmit -p ./tests"
|
|
||||||
},
|
|
||||||
"lint:types": {
|
|
||||||
"command": "tsc --noEmit -p .",
|
|
||||||
"dependencies": [
|
|
||||||
"build-locales",
|
|
||||||
"lint:types:tests"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"lint:lockfile": {
|
"lint:lockfile": {
|
||||||
"__comment": "The lockfile-lint package does not have an option to ensure resolved hashes are set everywhere",
|
"__comment": "The lockfile-lint package does not have an option to ensure resolved hashes are set everywhere",
|
||||||
"shell": true,
|
"shell": true,
|
||||||
@ -287,27 +265,6 @@
|
|||||||
"./packages/sfe:lint:lockfile"
|
"./packages/sfe:lint:lockfile"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lint:package": {
|
|
||||||
"command": "syncpack format -i ' '"
|
|
||||||
},
|
|
||||||
"lint:nightmare": {
|
|
||||||
"command": "${NODE_RUNNER} ./scripts/eslint.mjs --nightmare",
|
|
||||||
"env": {
|
|
||||||
"NODE_RUNNER": {
|
|
||||||
"external": true,
|
|
||||||
"default": "node"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint:precommit": {
|
|
||||||
"command": "${NODE_RUNNER} ./scripts/eslint.mjs --precommit",
|
|
||||||
"env": {
|
|
||||||
"NODE_RUNNER": {
|
|
||||||
"external": true,
|
|
||||||
"default": "node"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint:spelling": {
|
"lint:spelling": {
|
||||||
"command": "node scripts/check-spelling.mjs"
|
"command": "node scripts/check-spelling.mjs"
|
||||||
},
|
},
|
||||||
@ -317,13 +274,10 @@
|
|||||||
"precommit": {
|
"precommit": {
|
||||||
"command": "prettier --write .",
|
"command": "prettier --write .",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"lint:types",
|
|
||||||
"lint:components",
|
"lint:components",
|
||||||
"lint:spelling",
|
"lint:spelling",
|
||||||
"lint:package",
|
|
||||||
"lint:lockfile",
|
"lint:lockfile",
|
||||||
"lint:lockfiles",
|
"lint:lockfiles",
|
||||||
"lint:precommit",
|
|
||||||
"format:packages"
|
"format:packages"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -332,9 +286,6 @@
|
|||||||
"format"
|
"format"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"prettier-check": {
|
|
||||||
"command": "prettier --check ."
|
|
||||||
},
|
|
||||||
"pseudolocalize": {
|
"pseudolocalize": {
|
||||||
"command": "node scripts/pseudolocalize.mjs"
|
"command": "node scripts/pseudolocalize.mjs"
|
||||||
},
|
},
|
||||||
@ -378,15 +329,18 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"TS_NODE_PROJECT": "tsconfig.test.json"
|
"TS_NODE_PROJECT": "tsconfig.test.json"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"tsc": {
|
|
||||||
"dependencies": [
|
|
||||||
"lint:types"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"engines": {
|
||||||
".",
|
"node": ">=22.14.0"
|
||||||
"./packages/*"
|
},
|
||||||
]
|
"prettier": "@goauthentik/prettier-config",
|
||||||
|
"overrides": {
|
||||||
|
"rapidoc": {
|
||||||
|
"@apitools/openapi-parser@": "0.0.37"
|
||||||
|
},
|
||||||
|
"chromedriver": {
|
||||||
|
"axios": "^1.8.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"arrowParens": "always",
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"embeddedLanguageFormatting": "auto",
|
|
||||||
"htmlWhitespaceSensitivity": "css",
|
|
||||||
"insertPragma": false,
|
|
||||||
"jsxSingleQuote": false,
|
|
||||||
"printWidth": 100,
|
|
||||||
"proseWrap": "preserve",
|
|
||||||
"quoteProps": "consistent",
|
|
||||||
"requirePragma": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": false,
|
|
||||||
"tabWidth": 4,
|
|
||||||
"trailingComma": "all",
|
|
||||||
"useTabs": false,
|
|
||||||
"vueIndentScriptAndStyle": false,
|
|
||||||
"plugins": ["@trivago/prettier-plugin-sort-imports"],
|
|
||||||
"importOrder": ["^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
|
|
||||||
"importOrderSeparation": true,
|
|
||||||
"importOrderSortSpecifiers": true,
|
|
||||||
"importOrderParserPlugins": ["typescript", "classProperties", "decorators-legacy"]
|
|
||||||
}
|
|
@ -1,6 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/web-sfe",
|
"name": "@goauthentik/web-sfe",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "wireit",
|
||||||
|
"lint:lockfile": "wireit",
|
||||||
|
"prettier": "prettier --write ./src ./tsconfig.json ./rollup.config.js ./package.json",
|
||||||
|
"watch": "rollup -w -c rollup.config.js --bundleConfigAsCjs"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@goauthentik/api": "^2024.6.0-1719577139",
|
"@goauthentik/api": "^2024.6.0-1719577139",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
@ -10,6 +18,7 @@
|
|||||||
"weakmap-polyfill": "^2.0.4"
|
"weakmap-polyfill": "^2.0.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@goauthentik/prettier-config": "^1.0.4",
|
||||||
"@rollup/plugin-commonjs": "^28.0.0",
|
"@rollup/plugin-commonjs": "^28.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||||
"@rollup/plugin-swc": "^0.4.0",
|
"@rollup/plugin-swc": "^0.4.0",
|
||||||
@ -18,12 +27,11 @@
|
|||||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"@types/jquery": "^3.5.31",
|
"@types/jquery": "^3.5.31",
|
||||||
"lockfile-lint": "^4.14.0",
|
"lockfile-lint": "^4.14.0",
|
||||||
"prettier": "^3.3.2",
|
"prettier": "^3.5.3",
|
||||||
"rollup": "^4.23.0",
|
"rollup": "^4.23.0",
|
||||||
"rollup-plugin-copy": "^3.5.0",
|
"rollup-plugin-copy": "^3.5.0",
|
||||||
"wireit": "^0.14.9"
|
"wireit": "^0.14.9"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@swc/core": "^1.7.28",
|
"@swc/core": "^1.7.28",
|
||||||
"@swc/core-darwin-arm64": "^1.6.13",
|
"@swc/core-darwin-arm64": "^1.6.13",
|
||||||
@ -37,13 +45,6 @@
|
|||||||
"@swc/core-win32-ia32-msvc": "^1.6.13",
|
"@swc/core-win32-ia32-msvc": "^1.6.13",
|
||||||
"@swc/core-win32-x64-msvc": "^1.6.13"
|
"@swc/core-win32-x64-msvc": "^1.6.13"
|
||||||
},
|
},
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"build": "wireit",
|
|
||||||
"lint:lockfile": "wireit",
|
|
||||||
"prettier": "prettier --write ./src ./tsconfig.json ./rollup.config.js ./package.json",
|
|
||||||
"watch": "rollup -w -c rollup.config.js --bundleConfigAsCjs"
|
|
||||||
},
|
|
||||||
"wireit": {
|
"wireit": {
|
||||||
"build:sfe": {
|
"build:sfe": {
|
||||||
"command": "rollup -c rollup.config.js --bundleConfigAsCjs",
|
"command": "rollup -c rollup.config.js --bundleConfigAsCjs",
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import { fromByteArray } from "base64-js";
|
// sort-imports-ignore
|
||||||
|
|
||||||
import "formdata-polyfill";
|
import "formdata-polyfill";
|
||||||
import $ from "jquery";
|
|
||||||
import "weakmap-polyfill";
|
import "weakmap-polyfill";
|
||||||
|
|
||||||
|
import { fromByteArray } from "base64-js";
|
||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type AuthenticatorValidationChallenge,
|
type AuthenticatorValidationChallenge,
|
||||||
type AutosubmitChallenge,
|
type AutosubmitChallenge,
|
||||||
@ -273,7 +276,7 @@ class AuthenticatorValidateStage extends Stage<AuthenticatorValidationChallenge>
|
|||||||
deviceChallenge?: DeviceChallenge;
|
deviceChallenge?: DeviceChallenge;
|
||||||
|
|
||||||
b64enc(buf: Uint8Array): string {
|
b64enc(buf: Uint8Array): string {
|
||||||
return fromByteArray(buf).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
return fromByteArray(buf).replace(/\+/g, "-").replace(/\//g, "_").replace(/[=]/g, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
b64RawEnc(buf: Uint8Array): string {
|
b64RawEnc(buf: Uint8Array): string {
|
||||||
|
78
web/paths.js
Normal file
78
web/paths.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { dirname, resolve } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
const relativeDirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
//#region Base paths
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {'@goauthentik/web'} WebPackageIdentifier
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root of the web package.
|
||||||
|
*/
|
||||||
|
export const PackageRoot = /** @type {WebPackageIdentifier} */ (resolve(relativeDirname));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the distribution directory.
|
||||||
|
*/
|
||||||
|
export const DistDirectoryName = "dist";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to the web package's distribution directory.
|
||||||
|
*
|
||||||
|
* This is where the built files are located after running the build process.
|
||||||
|
*/
|
||||||
|
export const DistDirectory = /** @type {`${WebPackageIdentifier}/${DistDirectoryName}`} */ (
|
||||||
|
resolve(relativeDirname, DistDirectoryName)
|
||||||
|
);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region Entry points
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{ in: string, out: string }} EntryPointTarget
|
||||||
|
*
|
||||||
|
* ESBuild entrypoint target.
|
||||||
|
* Matches the type defined in the ESBuild context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry points available for building.
|
||||||
|
*
|
||||||
|
* @satisfies {Record<string, EntryPointTarget>}
|
||||||
|
*/
|
||||||
|
export const EntryPoint = /** @type {const} */ ({
|
||||||
|
Admin: {
|
||||||
|
in: resolve(PackageRoot, "src", "admin", "AdminInterface", "index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "admin", "AdminInterface"),
|
||||||
|
},
|
||||||
|
User: {
|
||||||
|
in: resolve(PackageRoot, "src", "user", "index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "user", "UserInterface"),
|
||||||
|
},
|
||||||
|
Flow: {
|
||||||
|
in: resolve(PackageRoot, "src", "flow", "index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "flow", "FlowInterface"),
|
||||||
|
},
|
||||||
|
Standalone: {
|
||||||
|
in: resolve(PackageRoot, "src", "standalone", "api-browser/index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "standalone", "api-browser", "index"),
|
||||||
|
},
|
||||||
|
StandaloneLoading: {
|
||||||
|
in: resolve(PackageRoot, "src", "standalone", "loading/index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "standalone", "loading", "index"),
|
||||||
|
},
|
||||||
|
RAC: {
|
||||||
|
in: resolve(PackageRoot, "src", "rac", "index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "rac", "index"),
|
||||||
|
},
|
||||||
|
Polyfill: {
|
||||||
|
in: resolve(PackageRoot, "src", "polyfill", "index.entrypoint.ts"),
|
||||||
|
out: resolve(DistDirectory, "poly"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//#endregion
|
@ -1,7 +1,7 @@
|
|||||||
import { spawnSync } from "child_process";
|
import { spawnSync } from "node:child_process";
|
||||||
import fs from "fs";
|
import fs from "node:fs";
|
||||||
import path from "path";
|
import path from "node:path";
|
||||||
import process from "process";
|
import process from "node:process";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if all the Xliff translation source files are present and if the Typescript source
|
* Determines if all the Xliff translation source files are present and if the Typescript source
|
||||||
@ -12,6 +12,9 @@ import process from "process";
|
|||||||
|
|
||||||
const localizeRules = JSON.parse(fs.readFileSync("./lit-localize.json", "utf-8"));
|
const localizeRules = JSON.parse(fs.readFileSync("./lit-localize.json", "utf-8"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} loc
|
||||||
|
*/
|
||||||
function generatedFileIsUpToDateWithXliffSource(loc) {
|
function generatedFileIsUpToDateWithXliffSource(loc) {
|
||||||
const xliff = path.join("./xliff", `${loc}.xlf`);
|
const xliff = path.join("./xliff", `${loc}.xlf`);
|
||||||
const gened = path.join("./src/locales", `${loc}.ts`);
|
const gened = path.join("./src/locales", `${loc}.ts`);
|
||||||
@ -21,16 +24,26 @@ function generatedFileIsUpToDateWithXliffSource(loc) {
|
|||||||
// than the generated file. The missing XLF file is important enough it
|
// than the generated file. The missing XLF file is important enough it
|
||||||
// generates a unique error message and halts the build.
|
// generates a unique error message and halts the build.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {fs.Stats}
|
||||||
|
*/
|
||||||
|
let xlfStat;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var xlfStat = fs.statSync(xliff);
|
xlfStat = fs.statSync(xliff);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
console.error(`lit-localize expected '${loc}.xlf', but XLF file is not present`);
|
console.error(`lit-localize expected '${loc}.xlf', but XLF file is not present`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {fs.Stats}
|
||||||
|
*/
|
||||||
|
let genedStat;
|
||||||
|
|
||||||
// If the generated file doesn't exist, of course it's not up to date.
|
// If the generated file doesn't exist, of course it's not up to date.
|
||||||
try {
|
try {
|
||||||
var genedStat = fs.statSync(gened);
|
genedStat = fs.statSync(gened);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,137 +1,92 @@
|
|||||||
import { execFileSync } from "child_process";
|
/**
|
||||||
|
* @file ESBuild script for building the authentik web UI.
|
||||||
|
*
|
||||||
|
* @import { BuildOptions } from "esbuild";
|
||||||
|
*/
|
||||||
|
import { liveReloadPlugin } from "@goauthentik/esbuild-plugin-live-reload/plugin";
|
||||||
|
import {
|
||||||
|
MonoRepoRoot,
|
||||||
|
NodeEnvironment,
|
||||||
|
readBuildIdentifier,
|
||||||
|
resolvePackage,
|
||||||
|
serializeEnvironmentVars,
|
||||||
|
} from "@goauthentik/monorepo";
|
||||||
|
import { DistDirectory, DistDirectoryName, EntryPoint, PackageRoot } from "@goauthentik/web/paths";
|
||||||
import { deepmerge } from "deepmerge-ts";
|
import { deepmerge } from "deepmerge-ts";
|
||||||
import esbuild from "esbuild";
|
import esbuild from "esbuild";
|
||||||
|
import copy from "esbuild-plugin-copy";
|
||||||
import { polyfillNode } from "esbuild-plugin-polyfill-node";
|
import { polyfillNode } from "esbuild-plugin-polyfill-node";
|
||||||
import findFreePorts from "find-free-ports";
|
import findFreePorts from "find-free-ports";
|
||||||
import { copyFileSync, mkdirSync, readFileSync, statSync } from "fs";
|
import * as fs from "node:fs/promises";
|
||||||
import { globSync } from "glob";
|
import * as path from "node:path";
|
||||||
import * as path from "path";
|
import process from "node:process";
|
||||||
import { cwd } from "process";
|
|
||||||
import process from "process";
|
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
|
|
||||||
import { mdxPlugin } from "./esbuild/build-mdx-plugin.mjs";
|
import { mdxPlugin } from "./esbuild/build-mdx-plugin.mjs";
|
||||||
import { buildObserverPlugin } from "./esbuild/build-observer-plugin.mjs";
|
|
||||||
|
|
||||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
const logPrefix = "[Build]";
|
||||||
let authentikProjectRoot = path.join(__dirname, "..", "..");
|
|
||||||
|
|
||||||
try {
|
const definitions = serializeEnvironmentVars({
|
||||||
// Use the package.json file in the root folder, as it has the current version information.
|
NODE_ENV: NodeEnvironment,
|
||||||
authentikProjectRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
CWD: process.cwd(),
|
||||||
encoding: "utf8",
|
AK_API_BASE_PATH: process.env.AK_API_BASE_PATH,
|
||||||
}).replace("\n", "");
|
WATCHER_URL: process.env.WATCHER_URL,
|
||||||
} catch (_error) {
|
});
|
||||||
// We probably don't have a .git folder, which could happen in container builds.
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageJSONPath = path.join(authentikProjectRoot, "./package.json");
|
const patternflyPath = resolvePackage("@patternfly/patternfly");
|
||||||
const rootPackage = JSON.parse(readFileSync(packageJSONPath, "utf8"));
|
|
||||||
|
|
||||||
const NODE_ENV = process.env.NODE_ENV || "development";
|
|
||||||
const AK_API_BASE_PATH = process.env.AK_API_BASE_PATH || "";
|
|
||||||
|
|
||||||
const environmentVars = new Map([
|
|
||||||
["NODE_ENV", NODE_ENV],
|
|
||||||
["CWD", cwd()],
|
|
||||||
["AK_API_BASE_PATH", AK_API_BASE_PATH],
|
|
||||||
]);
|
|
||||||
|
|
||||||
const definitions = Object.fromEntries(
|
|
||||||
Array.from(environmentVars).map(([key, value]) => {
|
|
||||||
return [`process.env.${key}`, JSON.stringify(value)];
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All is magic is just to make sure the assets are copied into the right places. This is a very
|
* @type {Readonly<BuildOptions>}
|
||||||
* stripped down version of what the rollup-copy-plugin does, without any of the features we don't
|
|
||||||
* use, and using globSync instead of globby since we already had globSync lying around thanks to
|
|
||||||
* Typescript. If there's a third argument in an array entry, it's used to replace the internal path
|
|
||||||
* before concatenating it all together as the destination target.
|
|
||||||
* @type {Array<[string, string, string?]>}
|
|
||||||
*/
|
|
||||||
const assetsFileMappings = [
|
|
||||||
["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
|
|
||||||
["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
|
|
||||||
["src/common/styles/**", "."],
|
|
||||||
["src/assets/images/**", "./assets/images"],
|
|
||||||
["./icons/*", "./assets/icons"],
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} filePath
|
|
||||||
*/
|
|
||||||
const isFile = (filePath) => statSync(filePath).isFile();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} src Source file
|
|
||||||
* @param {string} dest Destination folder
|
|
||||||
* @param {string} [strip] Path to strip from the source file
|
|
||||||
*/
|
|
||||||
function nameCopyTarget(src, dest, strip) {
|
|
||||||
const target = path.join(dest, strip ? src.replace(strip, "") : path.parse(src).base);
|
|
||||||
return [src, target];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [source, rawdest, strip] of assetsFileMappings) {
|
|
||||||
const matchedPaths = globSync(source);
|
|
||||||
const dest = path.join("dist", rawdest);
|
|
||||||
|
|
||||||
const copyTargets = matchedPaths.map((path) => nameCopyTarget(path, dest, strip));
|
|
||||||
|
|
||||||
for (const [src, dest] of copyTargets) {
|
|
||||||
if (isFile(src)) {
|
|
||||||
mkdirSync(path.dirname(dest), { recursive: true });
|
|
||||||
copyFileSync(src, dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {[source: string, destination: string]} EntryPoint
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This starts the definitions used for esbuild: Our targets, our arguments, the function for
|
|
||||||
* running a build, and three options for building: watching, building, and building the proxy.
|
|
||||||
* Ordered by largest to smallest interface to build even faster
|
|
||||||
*
|
|
||||||
* @type {EntryPoint[]}
|
|
||||||
*/
|
|
||||||
const entryPoints = [
|
|
||||||
["admin/AdminInterface/AdminInterface.ts", "admin"],
|
|
||||||
["user/UserInterface.ts", "user"],
|
|
||||||
["flow/FlowInterface.ts", "flow"],
|
|
||||||
["standalone/api-browser/index.ts", "standalone/api-browser"],
|
|
||||||
["rac/index.ts", "rac"],
|
|
||||||
["standalone/loading/index.ts", "standalone/loading"],
|
|
||||||
["polyfill/poly.ts", "."],
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {import("esbuild").BuildOptions}
|
|
||||||
*/
|
*/
|
||||||
const BASE_ESBUILD_OPTIONS = {
|
const BASE_ESBUILD_OPTIONS = {
|
||||||
|
entryNames: `[dir]/[name]-${readBuildIdentifier()}`,
|
||||||
|
chunkNames: "[dir]/chunks/[name]-[hash]",
|
||||||
|
assetNames: "assets/[dir]/[name]-[hash]",
|
||||||
|
publicPath: path.join("/static", DistDirectoryName),
|
||||||
|
outdir: DistDirectory,
|
||||||
bundle: true,
|
bundle: true,
|
||||||
write: true,
|
write: true,
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
minify: NODE_ENV === "production",
|
minify: NodeEnvironment === "production",
|
||||||
|
legalComments: "external",
|
||||||
splitting: true,
|
splitting: true,
|
||||||
treeShaking: true,
|
treeShaking: true,
|
||||||
external: ["*.woff", "*.woff2"],
|
external: ["*.woff", "*.woff2"],
|
||||||
tsconfig: "./tsconfig.json",
|
tsconfig: path.resolve(PackageRoot, "tsconfig.build.json"),
|
||||||
loader: {
|
loader: {
|
||||||
".css": "text",
|
".css": "text",
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
copy({
|
||||||
|
assets: [
|
||||||
|
{
|
||||||
|
from: path.join(patternflyPath, "patternfly.min.css"),
|
||||||
|
to: ".",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: path.join(patternflyPath, "assets", "**"),
|
||||||
|
to: "./assets",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: path.resolve(PackageRoot, "src", "common", "styles", "**"),
|
||||||
|
to: ".",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: path.resolve(PackageRoot, "src", "assets", "images", "**"),
|
||||||
|
to: "./assets/images",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: path.resolve(PackageRoot, "icons", "*"),
|
||||||
|
to: "./assets/icons",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
polyfillNode({
|
polyfillNode({
|
||||||
polyfills: {
|
polyfills: {
|
||||||
path: true,
|
path: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
mdxPlugin({
|
mdxPlugin({
|
||||||
root: authentikProjectRoot,
|
root: MonoRepoRoot,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
define: definitions,
|
define: definitions,
|
||||||
@ -147,69 +102,42 @@ const BASE_ESBUILD_OPTIONS = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
async function cleanDistDirectory() {
|
||||||
* Creates a version ID for the build.
|
const timerLabel = `${logPrefix} ♻️ Cleaning previous builds...`;
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function composeVersionID() {
|
|
||||||
const { version } = rootPackage;
|
|
||||||
const buildHash = process.env.GIT_BUILD_HASH;
|
|
||||||
|
|
||||||
if (buildHash) {
|
console.time(timerLabel);
|
||||||
return `${version}+${buildHash}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return version;
|
await fs.rm(DistDirectory, {
|
||||||
|
recursive: true,
|
||||||
|
force: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await fs.mkdir(DistDirectory, {
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.timeEnd(timerLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a single entry point.
|
* Creates an ESBuild options, extending the base options with the given overrides.
|
||||||
*
|
*
|
||||||
* @param {EntryPoint} buildTarget
|
* @param {BuildOptions} overrides
|
||||||
* @param {Partial<esbuild.BuildOptions>} [overrides]
|
* @returns {BuildOptions}
|
||||||
* @throws {Error} on build failure
|
|
||||||
*/
|
*/
|
||||||
function createEntryPointOptions([source, dest], overrides = {}) {
|
export function createESBuildOptions(overrides) {
|
||||||
const outdir = path.join(__dirname, "..", "dist", dest);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {esbuild.BuildOptions}
|
* @type {BuildOptions}
|
||||||
*/
|
*/
|
||||||
|
const mergedOptions = deepmerge(BASE_ESBUILD_OPTIONS, overrides);
|
||||||
|
|
||||||
const entryPointConfig = {
|
return mergedOptions;
|
||||||
entryPoints: [`./src/${source}`],
|
|
||||||
entryNames: `[dir]/[name]-${composeVersionID()}`,
|
|
||||||
publicPath: path.join("/static", "dist", dest),
|
|
||||||
outdir,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {esbuild.BuildOptions}
|
|
||||||
*/
|
|
||||||
const mergedConfig = deepmerge(BASE_ESBUILD_OPTIONS, entryPointConfig, overrides);
|
|
||||||
|
|
||||||
return mergedConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build all entry points in parallel.
|
|
||||||
*
|
|
||||||
* @param {EntryPoint[]} entryPoints
|
|
||||||
* @returns {Promise<esbuild.BuildResult[]>}
|
|
||||||
*/
|
|
||||||
async function buildParallel(entryPoints) {
|
|
||||||
return Promise.all(
|
|
||||||
entryPoints.map((entryPoint) => {
|
|
||||||
return esbuild.build(createEntryPointOptions(entryPoint));
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function doHelp() {
|
function doHelp() {
|
||||||
console.log(`Build the authentik UI
|
console.log(`Build the authentik UI
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-w, --watch: Build all ${entryPoints.length} interfaces
|
-w, --watch: Build all interfaces
|
||||||
-p, --proxy: Build only the polyfills and the loading application
|
-p, --proxy: Build only the polyfills and the loading application
|
||||||
-h, --help: This help message
|
-h, --help: This help message
|
||||||
`);
|
`);
|
||||||
@ -218,36 +146,37 @@ function doHelp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function doWatch() {
|
async function doWatch() {
|
||||||
console.log("Watching all entry points...");
|
console.group(`${logPrefix} 🤖 Watching entry points`);
|
||||||
|
|
||||||
const wathcherPorts = await findFreePorts(entryPoints.length);
|
const entryPoints = Object.entries(EntryPoint).map(([entrypointID, target]) => {
|
||||||
|
console.log(entrypointID);
|
||||||
|
|
||||||
const buildContexts = await Promise.all(
|
return target;
|
||||||
entryPoints.map((entryPoint, i) => {
|
});
|
||||||
const port = wathcherPorts[i];
|
|
||||||
const serverURL = new URL(`http://localhost:${port}/events`);
|
|
||||||
|
|
||||||
return esbuild.context(
|
console.groupEnd();
|
||||||
createEntryPointOptions(entryPoint, {
|
|
||||||
plugins: [
|
const wathcherPorts = await findFreePorts(1);
|
||||||
buildObserverPlugin({
|
const port = wathcherPorts[0];
|
||||||
serverURL,
|
const serverURL = new URL(`http://localhost:${port}/events`);
|
||||||
logPrefix: entryPoint[1],
|
|
||||||
relativeRoot: path.join(__dirname, ".."),
|
const buildOptions = createESBuildOptions({
|
||||||
}),
|
entryPoints,
|
||||||
],
|
plugins: [
|
||||||
define: {
|
liveReloadPlugin({
|
||||||
...definitions,
|
serverURL,
|
||||||
"process.env.WATCHER_URL": JSON.stringify(serverURL.toString()),
|
relativeRoot: PackageRoot,
|
||||||
},
|
}),
|
||||||
}),
|
],
|
||||||
);
|
define: serializeEnvironmentVars({
|
||||||
|
WATCHER_URL: serverURL.toString(),
|
||||||
}),
|
}),
|
||||||
);
|
});
|
||||||
|
|
||||||
await Promise.all(buildContexts.map((context) => context.rebuild()));
|
const buildContext = await esbuild.context(buildOptions);
|
||||||
|
|
||||||
await Promise.allSettled(buildContexts.map((context) => context.watch()));
|
await buildContext.rebuild();
|
||||||
|
await buildContext.watch();
|
||||||
|
|
||||||
return /** @type {Promise<void>} */ (
|
return /** @type {Promise<void>} */ (
|
||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
@ -259,15 +188,34 @@ async function doWatch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function doBuild() {
|
async function doBuild() {
|
||||||
console.log("Building all entry points");
|
console.group(`${logPrefix} 🚀 Building entry points:`);
|
||||||
|
|
||||||
return buildParallel(entryPoints);
|
const entryPoints = Object.entries(EntryPoint).map(([entrypointID, target]) => {
|
||||||
|
console.log(entrypointID);
|
||||||
|
|
||||||
|
return target;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
|
||||||
|
const buildOptions = createESBuildOptions({
|
||||||
|
entryPoints,
|
||||||
|
});
|
||||||
|
|
||||||
|
await esbuild.build(buildOptions);
|
||||||
|
|
||||||
|
console.log("Build complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doProxy() {
|
async function doProxy() {
|
||||||
return buildParallel(
|
const entryPoints = [EntryPoint.StandaloneLoading];
|
||||||
entryPoints.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)),
|
|
||||||
);
|
const buildOptions = createESBuildOptions({
|
||||||
|
entryPoints,
|
||||||
|
});
|
||||||
|
|
||||||
|
await esbuild.build(buildOptions);
|
||||||
|
console.log("Proxy build complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function delegateCommand() {
|
async function delegateCommand() {
|
||||||
@ -289,12 +237,16 @@ async function delegateCommand() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await delegateCommand()
|
await cleanDistDirectory()
|
||||||
.then(() => {
|
// ---
|
||||||
console.log("Build complete");
|
.then(() =>
|
||||||
process.exit(0);
|
delegateCommand()
|
||||||
})
|
.then(() => {
|
||||||
.catch((error) => {
|
console.log("Build complete");
|
||||||
console.error(error);
|
process.exit(0);
|
||||||
process.exit(1);
|
})
|
||||||
});
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { execSync } from "child_process";
|
import { execSync } from "node:child_process";
|
||||||
import path from "path";
|
import path from "node:path";
|
||||||
|
|
||||||
const projectRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf8" }).replace(
|
const projectRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf8" }).replace(
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
import { execFileSync } from "child_process";
|
|
||||||
import { ESLint } from "eslint";
|
|
||||||
import fs from "fs";
|
|
||||||
import path from "path";
|
|
||||||
import process from "process";
|
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
|
|
||||||
function changedFiles() {
|
|
||||||
const gitStatus = execFileSync("git", ["diff", "--name-only", "HEAD"], { encoding: "utf8" });
|
|
||||||
const gitUntracked = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
||||||
encoding: "utf8",
|
|
||||||
});
|
|
||||||
|
|
||||||
const changed = gitStatus
|
|
||||||
.split("\n")
|
|
||||||
.filter((line) => line.trim().substring(0, 4) === "web/")
|
|
||||||
.filter((line) => /\.(m|c)?(t|j)s$/.test(line))
|
|
||||||
.map((line) => line.substring(4))
|
|
||||||
.filter((line) => fs.existsSync(line));
|
|
||||||
|
|
||||||
const untracked = gitUntracked
|
|
||||||
.split("\n")
|
|
||||||
.filter((line) => /\.(m|c)?(t|j)s$/.test(line))
|
|
||||||
.filter((line) => fs.existsSync(line));
|
|
||||||
|
|
||||||
const sourceFiles = [...changed, ...untracked].filter((line) => /^src\//.test(line));
|
|
||||||
const scriptFiles = [...changed, ...untracked].filter(
|
|
||||||
(line) => /^scripts\//.test(line) || !/^src\//.test(line),
|
|
||||||
);
|
|
||||||
|
|
||||||
return [...sourceFiles, ...scriptFiles];
|
|
||||||
}
|
|
||||||
|
|
||||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
||||||
const projectRoot = path.join(__dirname, "..");
|
|
||||||
process.chdir(projectRoot);
|
|
||||||
|
|
||||||
const hasFlag = (flags) => process.argv.length > 1 && flags.includes(process.argv[2]);
|
|
||||||
|
|
||||||
const [configFile, files] = hasFlag(["-n", "--nightmare"])
|
|
||||||
? [path.join(__dirname, "eslint.nightmare.mjs"), changedFiles()]
|
|
||||||
: hasFlag(["-p", "--precommit"])
|
|
||||||
? [path.join(__dirname, "eslint.precommit.mjs"), changedFiles()]
|
|
||||||
: [path.join(projectRoot, "eslint.config.mjs"), ["."]];
|
|
||||||
|
|
||||||
const eslint = new ESLint({
|
|
||||||
overrideConfigFile: configFile,
|
|
||||||
warnIgnored: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = await eslint.lintFiles(files);
|
|
||||||
const formatter = await eslint.loadFormatter("stylish");
|
|
||||||
const resultText = formatter.format(results);
|
|
||||||
const errors = results.reduce((acc, result) => acc + result.errorCount, 0);
|
|
||||||
console.log(resultText);
|
|
||||||
process.exit(errors > 1 ? 1 : 0);
|
|
@ -1,217 +0,0 @@
|
|||||||
import eslint from "@eslint/js";
|
|
||||||
import tsparser from "@typescript-eslint/parser";
|
|
||||||
import litconf from "eslint-plugin-lit";
|
|
||||||
import wcconf from "eslint-plugin-wc";
|
|
||||||
import globals from "globals";
|
|
||||||
import tseslint from "typescript-eslint";
|
|
||||||
|
|
||||||
const MAX_DEPTH = 4;
|
|
||||||
const MAX_NESTED_CALLBACKS = 4;
|
|
||||||
const MAX_PARAMS = 5;
|
|
||||||
|
|
||||||
// Waiting for SonarJS to be compatible
|
|
||||||
// const MAX_COGNITIVE_COMPLEXITY = 9;
|
|
||||||
|
|
||||||
const rules = {
|
|
||||||
"accessor-pairs": "error",
|
|
||||||
"array-callback-return": "error",
|
|
||||||
"block-scoped-var": "error",
|
|
||||||
"consistent-return": "error",
|
|
||||||
"consistent-this": ["error", "that"],
|
|
||||||
"curly": ["error", "all"],
|
|
||||||
"dot-notation": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
allowKeywords: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"eqeqeq": "error",
|
|
||||||
"func-names": "error",
|
|
||||||
"guard-for-in": "error",
|
|
||||||
"max-depth": ["error", MAX_DEPTH],
|
|
||||||
"max-nested-callbacks": ["error", MAX_NESTED_CALLBACKS],
|
|
||||||
"max-params": ["error", MAX_PARAMS],
|
|
||||||
"new-cap": "error",
|
|
||||||
"no-alert": "error",
|
|
||||||
"no-array-constructor": "error",
|
|
||||||
"no-bitwise": "error",
|
|
||||||
"no-caller": "error",
|
|
||||||
"no-case-declarations": "error",
|
|
||||||
"no-class-assign": "error",
|
|
||||||
"no-cond-assign": "error",
|
|
||||||
"no-const-assign": "error",
|
|
||||||
"no-constant-condition": "error",
|
|
||||||
"no-control-regex": "error",
|
|
||||||
"no-debugger": "error",
|
|
||||||
"no-delete-var": "error",
|
|
||||||
"no-div-regex": "error",
|
|
||||||
"no-dupe-args": "error",
|
|
||||||
"no-dupe-keys": "error",
|
|
||||||
"no-duplicate-case": "error",
|
|
||||||
"no-else-return": "error",
|
|
||||||
"no-empty": "error",
|
|
||||||
"no-empty-character-class": "error",
|
|
||||||
"no-empty-function": "error",
|
|
||||||
"no-labels": "error",
|
|
||||||
"no-eq-null": "error",
|
|
||||||
"no-eval": "error",
|
|
||||||
"no-ex-assign": "error",
|
|
||||||
"no-extend-native": "error",
|
|
||||||
"no-extra-bind": "error",
|
|
||||||
"no-extra-boolean-cast": "error",
|
|
||||||
"no-extra-label": "error",
|
|
||||||
"no-fallthrough": "error",
|
|
||||||
"no-func-assign": "error",
|
|
||||||
"no-implied-eval": "error",
|
|
||||||
"no-implicit-coercion": "error",
|
|
||||||
"no-implicit-globals": "error",
|
|
||||||
"no-inner-declarations": ["error", "functions"],
|
|
||||||
"no-invalid-regexp": "error",
|
|
||||||
"no-irregular-whitespace": "error",
|
|
||||||
"no-iterator": "error",
|
|
||||||
"no-invalid-this": "error",
|
|
||||||
"no-label-var": "error",
|
|
||||||
"no-lone-blocks": "error",
|
|
||||||
"no-lonely-if": "error",
|
|
||||||
"no-loop-func": "error",
|
|
||||||
"no-magic-numbers": ["error", { ignore: [0, 1, -1] }],
|
|
||||||
"no-multi-str": "error",
|
|
||||||
"no-negated-condition": "error",
|
|
||||||
"no-nested-ternary": "error",
|
|
||||||
"no-new": "error",
|
|
||||||
"no-new-func": "error",
|
|
||||||
"no-new-wrappers": "error",
|
|
||||||
"no-obj-calls": "error",
|
|
||||||
"no-octal": "error",
|
|
||||||
"no-octal-escape": "error",
|
|
||||||
"no-param-reassign": "error",
|
|
||||||
"no-proto": "error",
|
|
||||||
"no-redeclare": "error",
|
|
||||||
"no-regex-spaces": "error",
|
|
||||||
"no-restricted-syntax": ["error", "WithStatement"],
|
|
||||||
"no-script-url": "error",
|
|
||||||
"no-self-assign": "error",
|
|
||||||
"no-self-compare": "error",
|
|
||||||
"no-sequences": "error",
|
|
||||||
"no-shadow": "error",
|
|
||||||
"no-shadow-restricted-names": "error",
|
|
||||||
"no-sparse-arrays": "error",
|
|
||||||
"no-this-before-super": "error",
|
|
||||||
"no-throw-literal": "error",
|
|
||||||
"no-trailing-spaces": "error",
|
|
||||||
"no-undef": "error",
|
|
||||||
"no-undef-init": "error",
|
|
||||||
"no-unexpected-multiline": "error",
|
|
||||||
"no-useless-constructor": "error",
|
|
||||||
"no-unmodified-loop-condition": "error",
|
|
||||||
"no-unneeded-ternary": "error",
|
|
||||||
"no-unreachable": "error",
|
|
||||||
"no-unused-expressions": "error",
|
|
||||||
"no-unused-labels": "error",
|
|
||||||
"no-use-before-define": "error",
|
|
||||||
"no-useless-call": "error",
|
|
||||||
"no-dupe-class-members": "error",
|
|
||||||
"no-var": "error",
|
|
||||||
"no-void": "error",
|
|
||||||
"no-with": "error",
|
|
||||||
"prefer-arrow-callback": "error",
|
|
||||||
"prefer-const": "error",
|
|
||||||
"prefer-rest-params": "error",
|
|
||||||
"prefer-spread": "error",
|
|
||||||
"prefer-template": "error",
|
|
||||||
"radix": "error",
|
|
||||||
"require-yield": "error",
|
|
||||||
"strict": ["error", "global"],
|
|
||||||
"use-isnan": "error",
|
|
||||||
"valid-typeof": "error",
|
|
||||||
"vars-on-top": "error",
|
|
||||||
"yoda": ["error", "never"],
|
|
||||||
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
|
||||||
// SonarJS is not yet compatible with ESLint 9. Commenting these out
|
|
||||||
// until it is.
|
|
||||||
// "sonarjs/cognitive-complexity": ["off", MAX_COGNITIVE_COMPLEXITY],
|
|
||||||
// "sonarjs/no-duplicate-string": "off",
|
|
||||||
// "sonarjs/no-nested-template-literals": "off",
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
argsIgnorePattern: "^_",
|
|
||||||
varsIgnorePattern: "^_",
|
|
||||||
caughtErrorsIgnorePattern: "^_",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default [
|
|
||||||
// You would not believe how much this change has frustrated users: ["if an ignores key is used
|
|
||||||
// without any other keys in the configuration object, then the patterns act as global
|
|
||||||
// ignores"](https://eslint.org/docs/latest/use/configure/ignore)
|
|
||||||
{
|
|
||||||
ignores: [
|
|
||||||
"dist/",
|
|
||||||
".wireit/",
|
|
||||||
"packages/",
|
|
||||||
// don't ever lint node_modules
|
|
||||||
"node_modules/",
|
|
||||||
".storybook/*",
|
|
||||||
// don't lint build output (make sure it's set to your correct build folder name)
|
|
||||||
// don't lint nyc coverage output
|
|
||||||
"coverage/",
|
|
||||||
"src/locale-codes.ts",
|
|
||||||
"storybook-static/",
|
|
||||||
"src/locales/",
|
|
||||||
"src/**/*.test.ts",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
eslint.configs.recommended,
|
|
||||||
wcconf.configs["flat/recommended"],
|
|
||||||
litconf.configs["flat/recommended"],
|
|
||||||
...tseslint.configs.recommended,
|
|
||||||
// sonar.configs.recommended,
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
...globals.browser,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["src/**"],
|
|
||||||
rules,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
...globals.nodeBuiltin,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["scripts/*.mjs", "*.ts", "*.mjs"],
|
|
||||||
rules,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
...globals.nodeBuiltin,
|
|
||||||
...globals.jest,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["src/**/*.test.ts"],
|
|
||||||
rules,
|
|
||||||
},
|
|
||||||
];
|
|
@ -1,87 +0,0 @@
|
|||||||
import eslint from "@eslint/js";
|
|
||||||
import tsparser from "@typescript-eslint/parser";
|
|
||||||
import litconf from "eslint-plugin-lit";
|
|
||||||
import wcconf from "eslint-plugin-wc";
|
|
||||||
import globals from "globals";
|
|
||||||
import tseslint from "typescript-eslint";
|
|
||||||
|
|
||||||
export default [
|
|
||||||
// You would not believe how much this change has frustrated users: ["if an ignores key is used
|
|
||||||
// without any other keys in the configuration object, then the patterns act as global
|
|
||||||
// ignores"](https://eslint.org/docs/latest/use/configure/ignore)
|
|
||||||
{
|
|
||||||
ignores: [
|
|
||||||
"dist/",
|
|
||||||
".wireit/",
|
|
||||||
"packages/",
|
|
||||||
// don't ever lint node_modules
|
|
||||||
"node_modules/",
|
|
||||||
".storybook/*",
|
|
||||||
// don't lint build output (make sure it's set to your correct build folder name)
|
|
||||||
// don't lint nyc coverage output
|
|
||||||
"coverage/",
|
|
||||||
"src/locale-codes.ts",
|
|
||||||
"storybook-static/",
|
|
||||||
"src/locales/",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
eslint.configs.recommended,
|
|
||||||
wcconf.configs["flat/recommended"],
|
|
||||||
litconf.configs["flat/recommended"],
|
|
||||||
...tseslint.configs.recommended,
|
|
||||||
// sonar.configs.recommended,
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["src/**"],
|
|
||||||
rules: {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
|
||||||
// SonarJS is not yet compatible with ESLint 9. Commenting these out
|
|
||||||
// until it is.
|
|
||||||
// "sonarjs/cognitive-complexity": ["off", 9],
|
|
||||||
// "sonarjs/no-duplicate-string": "off",
|
|
||||||
// "sonarjs/no-nested-template-literals": "off",
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
argsIgnorePattern: "^_",
|
|
||||||
varsIgnorePattern: "^_",
|
|
||||||
caughtErrorsIgnorePattern: "^_",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
parser: tsparser,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 12,
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
...globals.nodeBuiltin,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
files: ["scripts/*.mjs", "*.ts", "*.mjs"],
|
|
||||||
rules: {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"no-console": "off",
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
argsIgnorePattern: "^_",
|
|
||||||
varsIgnorePattern: "^_",
|
|
||||||
caughtErrorsIgnorePattern: "^_",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
@ -1,7 +1,7 @@
|
|||||||
import { type KnipConfig } from "knip";
|
import { type KnipConfig } from "knip";
|
||||||
|
|
||||||
const config: KnipConfig = {
|
const config: KnipConfig = {
|
||||||
"entry": [
|
entry: [
|
||||||
"./src/admin/AdminInterface/AdminInterface.ts",
|
"./src/admin/AdminInterface/AdminInterface.ts",
|
||||||
"./src/user/UserInterface.ts",
|
"./src/user/UserInterface.ts",
|
||||||
"./src/flow/FlowInterface.ts",
|
"./src/flow/FlowInterface.ts",
|
||||||
@ -10,18 +10,18 @@ const config: KnipConfig = {
|
|||||||
"./src/standalone/loading/index.ts",
|
"./src/standalone/loading/index.ts",
|
||||||
"./src/polyfill/poly.ts",
|
"./src/polyfill/poly.ts",
|
||||||
],
|
],
|
||||||
"project": ["src/**/*.ts", "src/**/*.js", "./scripts/*.mjs", ".storybook/*.ts"],
|
project: ["src/**/*.ts", "src/**/*.js", "./scripts/*.mjs", ".storybook/*.ts"],
|
||||||
// "ignore": ["src/**/*.test.ts", "src/**/*.stories.ts"],
|
// "ignore": ["src/**/*.test.ts", "src/**/*.stories.ts"],
|
||||||
// Prevent Knip from complaining about web components, which export their classes but also
|
// Prevent Knip from complaining about web components, which export their classes but also
|
||||||
// export their registration, and we don't always use both.
|
// export their registration, and we don't always use both.
|
||||||
"ignoreExportsUsedInFile": true,
|
ignoreExportsUsedInFile: true,
|
||||||
"typescript": {
|
typescript: {
|
||||||
config: ["tsconfig.json"],
|
config: ["tsconfig.json"],
|
||||||
},
|
},
|
||||||
"wireit": {
|
wireit: {
|
||||||
config: ["package.json"],
|
config: ["package.json"],
|
||||||
},
|
},
|
||||||
"storybook": {
|
storybook: {
|
||||||
config: [".storybook/{main,test-runner}.{js,ts}"],
|
config: [".storybook/{main,test-runner}.{js,ts}"],
|
||||||
entry: [
|
entry: [
|
||||||
".storybook/{manager,preview}.{js,jsx,ts,tsx}",
|
".storybook/{manager,preview}.{js,jsx,ts,tsx}",
|
||||||
@ -29,7 +29,7 @@ const config: KnipConfig = {
|
|||||||
],
|
],
|
||||||
project: [".storybook/**/*.{js,jsx,ts,tsx}"],
|
project: [".storybook/**/*.{js,jsx,ts,tsx}"],
|
||||||
},
|
},
|
||||||
"eslint": {
|
eslint: {
|
||||||
entry: [
|
entry: [
|
||||||
"eslint.config.mjs",
|
"eslint.config.mjs",
|
||||||
"scripts/eslint.precommit.mjs",
|
"scripts/eslint.precommit.mjs",
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "node:fs";
|
||||||
import path from "path";
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
import pseudolocale from "pseudolocale";
|
import pseudolocale from "pseudolocale";
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
|
|
||||||
import { makeFormatter } from "@lit/localize-tools/lib/formatters/index.js";
|
import { makeFormatter } from "@lit/localize-tools/lib/formatters/index.js";
|
||||||
import { sortProgramMessages } from "@lit/localize-tools/lib/messages.js";
|
import { sortProgramMessages } from "@lit/localize-tools/lib/messages.js";
|
||||||
import { TransformLitLocalizer } from "@lit/localize-tools/lib/modes/transform.js";
|
import { TransformLitLocalizer } from "@lit/localize-tools/lib/modes/transform.js";
|
||||||
|
|
||||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
const relativeDirname = fileURLToPath(new URL(".", import.meta.url));
|
||||||
const pseudoLocale = "pseudo-LOCALE";
|
const pseudoLocale = "pseudo-LOCALE";
|
||||||
const targetLocales = [pseudoLocale];
|
const targetLocales = [pseudoLocale];
|
||||||
const baseConfig = JSON.parse(readFileSync(path.join(__dirname, "../lit-localize.json"), "utf-8"));
|
const baseConfig = JSON.parse(
|
||||||
|
readFileSync(path.join(relativeDirname, "../lit-localize.json"), "utf-8"),
|
||||||
|
);
|
||||||
|
|
||||||
// Need to make some internal specifications to satisfy the transformer. It doesn't actually matter
|
// Need to make some internal specifications to satisfy the transformer. It doesn't actually matter
|
||||||
// which Localizer we use (transformer or runtime), because all of the functionality we care about
|
// which Localizer we use (transformer or runtime), because all of the functionality we care about
|
||||||
@ -19,7 +21,7 @@ const baseConfig = JSON.parse(readFileSync(path.join(__dirname, "../lit-localize
|
|||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
...baseConfig,
|
...baseConfig,
|
||||||
baseDir: path.join(__dirname, ".."),
|
baseDir: path.join(relativeDirname, ".."),
|
||||||
targetLocales,
|
targetLocales,
|
||||||
output: {
|
output: {
|
||||||
...baseConfig.output,
|
...baseConfig.output,
|
||||||
@ -41,4 +43,8 @@ const translations = messages.map(pseudoMessagify);
|
|||||||
const sorted = sortProgramMessages([...messages]);
|
const sorted = sortProgramMessages([...messages]);
|
||||||
const formatter = makeFormatter(config);
|
const formatter = makeFormatter(config);
|
||||||
|
|
||||||
formatter.writeOutput(sorted, new Map([[pseudoLocale, translations]]));
|
formatter.writeOutput(
|
||||||
|
sorted,
|
||||||
|
// @ts-expect-error Needs typing.
|
||||||
|
new Map([[pseudoLocale, translations]]),
|
||||||
|
);
|
||||||
|
@ -2,9 +2,9 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
|||||||
import { VERSION } from "@goauthentik/common/constants";
|
import { VERSION } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
|
||||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
|
||||||
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
||||||
|
import { WithBrandConfig } from "@goauthentik/elements/mixins/brand";
|
||||||
|
import { WithLicenseSummary } from "@goauthentik/elements/mixins/license";
|
||||||
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
|
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -59,7 +59,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
|||||||
|
|
||||||
renderModal() {
|
renderModal() {
|
||||||
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
if (this.licenseSummary?.status !== LicenseSummaryStatusEnum.Unlicensed) {
|
||||||
product += ` ${msg("Enterprise")}`;
|
product += ` ${msg("Enterprise")}`;
|
||||||
}
|
}
|
||||||
return html`<div
|
return html`<div
|
||||||
|
@ -4,8 +4,8 @@ import { AKElement } from "@goauthentik/elements/Base";
|
|||||||
import {
|
import {
|
||||||
CapabilitiesEnum,
|
CapabilitiesEnum,
|
||||||
WithCapabilitiesConfig,
|
WithCapabilitiesConfig,
|
||||||
} from "@goauthentik/elements/Interface/capabilitiesProvider";
|
} from "@goauthentik/elements/mixins/capabilities";
|
||||||
import { WithVersion } from "@goauthentik/elements/Interface/versionProvider";
|
import { WithVersion } from "@goauthentik/elements/mixins/version";
|
||||||
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route";
|
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route";
|
||||||
import { getRootStyle } from "@goauthentik/elements/utils/getRootStyle";
|
import { getRootStyle } from "@goauthentik/elements/utils/getRootStyle";
|
||||||
import { spread } from "@open-wc/lit-helpers";
|
import { spread } from "@open-wc/lit-helpers";
|
||||||
@ -13,6 +13,7 @@ import { spread } from "@open-wc/lit-helpers";
|
|||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { TemplateResult, html, nothing } from "lit";
|
import { TemplateResult, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
import { classMap } from "lit/directives/class-map.js";
|
||||||
import { map } from "lit/directives/map.js";
|
import { map } from "lit/directives/map.js";
|
||||||
|
|
||||||
import { UiThemeEnum } from "@goauthentik/api";
|
import { UiThemeEnum } from "@goauthentik/api";
|
||||||
@ -71,10 +72,12 @@ export class AkAdminSidebar extends WithCapabilitiesConfig(WithVersion(AKElement
|
|||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<ak-sidebar
|
<ak-sidebar
|
||||||
class="pf-c-page__sidebar ${this.open ? "pf-m-expanded" : "pf-m-collapsed"} ${this
|
class=${classMap({
|
||||||
.activeTheme === UiThemeEnum.Light
|
"pf-c-page__sidebar": true,
|
||||||
? "pf-m-light"
|
"pf-m-expanded": this.open,
|
||||||
: ""}"
|
"pf-m-collapsed": !this.open,
|
||||||
|
"pf-m-light": this.colorScheme === UiThemeEnum.Light,
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
${this.renderSidebarItems()}
|
${this.renderSidebarItems()}
|
||||||
</ak-sidebar>
|
</ak-sidebar>
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
import { configureSentry } from "@goauthentik/common/sentry";
|
import { configureSentry } from "@goauthentik/common/sentry";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
|
import { AKAuthenticatedInterfaceElement } from "@goauthentik/elements/Interface";
|
||||||
import "@goauthentik/elements/ak-locale-context";
|
import "@goauthentik/elements/ak-locale-context";
|
||||||
import "@goauthentik/elements/banner/EnterpriseStatusBanner";
|
import "@goauthentik/elements/banner/EnterpriseStatusBanner";
|
||||||
import "@goauthentik/elements/banner/VersionBanner";
|
import "@goauthentik/elements/banner/VersionBanner";
|
||||||
@ -30,12 +30,12 @@ import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
|
|||||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
import { SessionUser, UiThemeEnum } from "@goauthentik/api";
|
import { SessionUser } from "@goauthentik/api";
|
||||||
|
|
||||||
import "./AdminSidebar";
|
import "./AdminSidebar";
|
||||||
|
|
||||||
@customElement("ak-interface-admin")
|
@customElement("ak-interface-admin")
|
||||||
export class AdminInterface extends AuthenticatedInterface {
|
export class AdminInterface extends AKAuthenticatedInterfaceElement {
|
||||||
@property({ type: Boolean })
|
@property({ type: Boolean })
|
||||||
notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
|
notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
|
||||||
|
|
||||||
@ -123,15 +123,17 @@ export class AdminInterface extends AuthenticatedInterface {
|
|||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "development" && process.env.WATCHER_URL) {
|
if (process.env.NODE_ENV === "development" && process.env.WATCHER_URL) {
|
||||||
const { ESBuildObserver } = await import("@goauthentik/common/client");
|
const { ESBuildObserver } = await import(
|
||||||
|
"@goauthentik/esbuild-plugin-live-reload/client"
|
||||||
|
);
|
||||||
|
|
||||||
new ESBuildObserver(process.env.WATCHER_URL);
|
ESBuildObserver.initialize(process.env.WATCHER_URL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
const sidebarClasses = {
|
const sidebarClasses = {
|
||||||
"pf-m-light": this.activeTheme === UiThemeEnum.Light,
|
"pf-m-light": this.colorScheme === "light",
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawerOpen = this.notificationDrawerOpen || this.apiDrawerOpen;
|
const drawerOpen = this.notificationDrawerOpen || this.apiDrawerOpen;
|
@ -1,5 +1,5 @@
|
|||||||
import { AdminInterface } from "./AdminInterface";
|
import { AdminInterface } from "./index.entrypoint";
|
||||||
import "./AdminInterface";
|
import "./index.entrypoint";
|
||||||
|
|
||||||
export { AdminInterface };
|
export { AdminInterface };
|
||||||
export default AdminInterface;
|
export default AdminInterface;
|
||||||
|
@ -11,11 +11,11 @@ import "@goauthentik/admin/admin-overview/charts/SyncStatusChart";
|
|||||||
import { VERSION } from "@goauthentik/common/constants";
|
import { VERSION } from "@goauthentik/common/constants";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider.js";
|
|
||||||
import "@goauthentik/elements/PageHeader";
|
import "@goauthentik/elements/PageHeader";
|
||||||
import "@goauthentik/elements/cards/AggregatePromiseCard";
|
import "@goauthentik/elements/cards/AggregatePromiseCard";
|
||||||
import "@goauthentik/elements/cards/QuickActionsCard.js";
|
import "@goauthentik/elements/cards/QuickActionsCard.js";
|
||||||
import type { QuickAction } from "@goauthentik/elements/cards/QuickActionsCard.js";
|
import type { QuickAction } from "@goauthentik/elements/cards/QuickActionsCard.js";
|
||||||
|
import { WithLicenseSummary, isEnterpriseLicense } from "@goauthentik/elements/mixins/license.js";
|
||||||
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
|
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
@ -164,15 +164,16 @@ export class AdminOverviewPage extends AdminOverviewBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderCards() {
|
renderCards() {
|
||||||
const isEnterprise = this.hasEnterpriseLicense;
|
const enterprise = isEnterpriseLicense(this.licenseSummary);
|
||||||
|
|
||||||
const classes = {
|
const classes = {
|
||||||
"card-container": true,
|
"card-container": true,
|
||||||
"pf-l-grid__item": true,
|
"pf-l-grid__item": true,
|
||||||
"pf-m-6-col": true,
|
"pf-m-6-col": true,
|
||||||
"pf-m-4-col-on-md": !isEnterprise,
|
"pf-m-4-col-on-md": !enterprise,
|
||||||
"pf-m-4-col-on-xl": !isEnterprise,
|
"pf-m-4-col-on-xl": !enterprise,
|
||||||
"pf-m-3-col-on-md": isEnterprise,
|
"pf-m-3-col-on-md": enterprise,
|
||||||
"pf-m-3-col-on-xl": isEnterprise,
|
"pf-m-3-col-on-xl": enterprise,
|
||||||
};
|
};
|
||||||
|
|
||||||
return html`<div class=${classMap(classes)}>
|
return html`<div class=${classMap(classes)}>
|
||||||
@ -184,7 +185,7 @@ export class AdminOverviewPage extends AdminOverviewBase {
|
|||||||
<div class=${classMap(classes)}>
|
<div class=${classMap(classes)}>
|
||||||
<ak-admin-status-card-workers> </ak-admin-status-card-workers>
|
<ak-admin-status-card-workers> </ak-admin-status-card-workers>
|
||||||
</div>
|
</div>
|
||||||
${isEnterprise
|
${enterprise
|
||||||
? html` <div class=${classMap(classes)}>
|
? html` <div class=${classMap(classes)}>
|
||||||
<ak-admin-fips-status-system> </ak-admin-fips-status-system>
|
<ak-admin-fips-status-system> </ak-admin-fips-status-system>
|
||||||
</div>`
|
</div>`
|
||||||
|
@ -207,8 +207,8 @@ export class AdminSettingsForm extends Form<SettingsRequest> {
|
|||||||
.row=${(f?: FooterLink) =>
|
.row=${(f?: FooterLink) =>
|
||||||
akFooterLinkInput({
|
akFooterLinkInput({
|
||||||
".footerLink": f,
|
".footerLink": f,
|
||||||
"style": "width: 100%",
|
style: "width: 100%",
|
||||||
"name": "footer-link",
|
name: "footer-link",
|
||||||
} as unknown as IFooterLinkInput)}
|
} as unknown as IFooterLinkInput)}
|
||||||
>
|
>
|
||||||
</ak-array-input>
|
</ak-array-input>
|
||||||
|
@ -8,10 +8,6 @@ import "@goauthentik/components/ak-switch-input";
|
|||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import "@goauthentik/components/ak-textarea-input";
|
import "@goauthentik/components/ak-textarea-input";
|
||||||
import "@goauthentik/elements/Alert.js";
|
import "@goauthentik/elements/Alert.js";
|
||||||
import {
|
|
||||||
CapabilitiesEnum,
|
|
||||||
WithCapabilitiesConfig,
|
|
||||||
} from "@goauthentik/elements/Interface/capabilitiesProvider";
|
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import "@goauthentik/elements/forms/ModalForm";
|
import "@goauthentik/elements/forms/ModalForm";
|
||||||
@ -19,6 +15,10 @@ import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
|||||||
import "@goauthentik/elements/forms/ProxyForm";
|
import "@goauthentik/elements/forms/ProxyForm";
|
||||||
import "@goauthentik/elements/forms/Radio";
|
import "@goauthentik/elements/forms/Radio";
|
||||||
import "@goauthentik/elements/forms/SearchSelect";
|
import "@goauthentik/elements/forms/SearchSelect";
|
||||||
|
import {
|
||||||
|
CapabilitiesEnum,
|
||||||
|
WithCapabilitiesConfig,
|
||||||
|
} from "@goauthentik/elements/mixins/capabilities.js";
|
||||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user