Compare commits
	
		
			10 Commits
		
	
	
		
			dependabot
			...
			workspace-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ab315504a4 | |||
| 89a24dc508 | |||
| 1fe72ee377 | |||
| 9f596079d9 | |||
| 6c444dffc6 | |||
| 3bcbb2c0f9 | |||
| 4e284818cf | |||
| ced3f16310 | |||
| b65aabafdc | |||
| b07439dbe7 | 
							
								
								
									
										6
									
								
								.github/actions/setup/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/actions/setup/action.yml
									
									
									
									
										vendored
									
									
								
							@ -28,9 +28,9 @@ runs:
 | 
			
		||||
    - name: Setup node
 | 
			
		||||
      uses: actions/setup-node@v4
 | 
			
		||||
      with:
 | 
			
		||||
        node-version-file: web/package.json
 | 
			
		||||
        node-version-file: package.json
 | 
			
		||||
        cache: "npm"
 | 
			
		||||
        cache-dependency-path: web/package-lock.json
 | 
			
		||||
        cache-dependency-path: package-lock.json
 | 
			
		||||
    - name: Setup go
 | 
			
		||||
      uses: actions/setup-go@v5
 | 
			
		||||
      with:
 | 
			
		||||
@ -44,7 +44,7 @@ runs:
 | 
			
		||||
      run: |
 | 
			
		||||
        export PSQL_TAG=${{ inputs.postgresql_version }}
 | 
			
		||||
        docker compose -f .github/actions/setup/docker-compose.yml up -d
 | 
			
		||||
        cd web && npm ci
 | 
			
		||||
        npm ci
 | 
			
		||||
    - name: Generate config
 | 
			
		||||
      shell: uv run python {0}
 | 
			
		||||
      run: |
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								.github/workflows/api-ts-publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.github/workflows/api-ts-publish.yml
									
									
									
									
										vendored
									
									
								
							@ -20,8 +20,11 @@ jobs:
 | 
			
		||||
          token: ${{ steps.generate_token.outputs.token }}
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: web/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          registry-url: "https://registry.npmjs.org"
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: |
 | 
			
		||||
          npm ci
 | 
			
		||||
      - name: Generate API Client
 | 
			
		||||
        run: make gen-client-ts
 | 
			
		||||
      - name: Publish package
 | 
			
		||||
@ -32,15 +35,13 @@ jobs:
 | 
			
		||||
        env:
 | 
			
		||||
          NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
 | 
			
		||||
      - name: Upgrade /web
 | 
			
		||||
        working-directory: web
 | 
			
		||||
        run: |
 | 
			
		||||
          export VERSION=`node -e 'console.log(require("../gen-ts-api/package.json").version)'`
 | 
			
		||||
          npm i @goauthentik/api@$VERSION
 | 
			
		||||
          export VERSION=`node -e 'console.log(require("./gen-ts-api/package.json").version)'`
 | 
			
		||||
          npm i @goauthentik/api@$VERSION -w @goauthentik/web
 | 
			
		||||
      - name: Upgrade /web/packages/sfe
 | 
			
		||||
        working-directory: web/packages/sfe
 | 
			
		||||
        run: |
 | 
			
		||||
          export VERSION=`node -e 'console.log(require("../gen-ts-api/package.json").version)'`
 | 
			
		||||
          npm i @goauthentik/api@$VERSION
 | 
			
		||||
          export VERSION=`node -e 'console.log(require("./gen-ts-api/package.json").version)'`
 | 
			
		||||
          npm i @goauthentik/api@$VERSION -w @goauthentik/web-sfe
 | 
			
		||||
      - uses: peter-evans/create-pull-request@v7
 | 
			
		||||
        id: cpr
 | 
			
		||||
        with:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								.github/workflows/ci-main.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.github/workflows/ci-main.yml
									
									
									
									
										vendored
									
									
								
							@ -193,23 +193,22 @@ jobs:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - name: Setup authentik env
 | 
			
		||||
        uses: ./.github/actions/setup
 | 
			
		||||
      - name: Setup e2e env (chrome, etc)
 | 
			
		||||
      - name: Setup E2E environment (Chrome, etc)
 | 
			
		||||
        run: |
 | 
			
		||||
          docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
 | 
			
		||||
      - id: cache-web
 | 
			
		||||
        uses: actions/cache@v4
 | 
			
		||||
        with:
 | 
			
		||||
          path: web/dist
 | 
			
		||||
          key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
 | 
			
		||||
      - name: prepare web ui
 | 
			
		||||
          key: ${{ runner.os }}-web-${{ hashFiles('package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
 | 
			
		||||
      - name: Prepare Web UI
 | 
			
		||||
        if: steps.cache-web.outputs.cache-hit != 'true'
 | 
			
		||||
        working-directory: web
 | 
			
		||||
        run: |
 | 
			
		||||
          npm ci
 | 
			
		||||
          make -C .. gen-client-ts
 | 
			
		||||
          npm run build
 | 
			
		||||
          npm run build:sfe
 | 
			
		||||
      - name: run e2e
 | 
			
		||||
          make gen-client-ts
 | 
			
		||||
          npm run build -w @goauthentik/web
 | 
			
		||||
          npm run build -w @goauthentik/web-sfe
 | 
			
		||||
      - name: Run E2E
 | 
			
		||||
        run: |
 | 
			
		||||
          uv run coverage run manage.py test ${{ matrix.job.glob }}
 | 
			
		||||
          uv run coverage xml
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								.github/workflows/ci-outpost.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/ci-outpost.yml
									
									
									
									
										vendored
									
									
								
							@ -26,7 +26,7 @@ jobs:
 | 
			
		||||
          mkdir -p web/dist
 | 
			
		||||
          mkdir -p website/help
 | 
			
		||||
          touch web/dist/test website/help/test
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - name: Generate Golang API Client
 | 
			
		||||
        run: make gen-client-go
 | 
			
		||||
      - name: golangci-lint
 | 
			
		||||
        uses: golangci/golangci-lint-action@v8
 | 
			
		||||
@ -43,7 +43,7 @@ jobs:
 | 
			
		||||
          go-version-file: "go.mod"
 | 
			
		||||
      - name: Setup authentik env
 | 
			
		||||
        uses: ./.github/actions/setup
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - name: Generate Golang API Client
 | 
			
		||||
        run: make gen-client-go
 | 
			
		||||
      - name: Go unittests
 | 
			
		||||
        run: |
 | 
			
		||||
@ -99,7 +99,7 @@ jobs:
 | 
			
		||||
          registry: ghcr.io
 | 
			
		||||
          username: ${{ github.repository_owner }}
 | 
			
		||||
          password: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - name: Generate Golang API Client
 | 
			
		||||
        run: make gen-client-go
 | 
			
		||||
      - name: Build Docker Image
 | 
			
		||||
        id: push
 | 
			
		||||
@ -145,16 +145,17 @@ jobs:
 | 
			
		||||
          go-version-file: "go.mod"
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: web/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: web/package-lock.json
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Generate Golang API Client
 | 
			
		||||
        run: make gen-client-go
 | 
			
		||||
      - name: Build web
 | 
			
		||||
        working-directory: web/
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: |
 | 
			
		||||
          npm ci
 | 
			
		||||
          npm run build-proxy
 | 
			
		||||
      - name: Run ESBuild
 | 
			
		||||
        run: |
 | 
			
		||||
          npm run build-proxy -w @goauthentik/web
 | 
			
		||||
      - name: Build outpost
 | 
			
		||||
        run: |
 | 
			
		||||
          set -x
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								.github/workflows/ci-web.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/ci-web.yml
									
									
									
									
										vendored
									
									
								
							@ -19,47 +19,45 @@ jobs:
 | 
			
		||||
      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
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: ${{ matrix.project }}/package-lock.json
 | 
			
		||||
      - working-directory: ${{ matrix.project }}/
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: |
 | 
			
		||||
          npm ci
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - name: Generate TypeScript API
 | 
			
		||||
        run: make gen-client-ts
 | 
			
		||||
      - name: Lint
 | 
			
		||||
        working-directory: ${{ matrix.project }}/
 | 
			
		||||
        run: npm run ${{ matrix.command }}
 | 
			
		||||
      - name: Lint Project
 | 
			
		||||
        run: |
 | 
			
		||||
          npm run build-locales -w @goauthentik/web
 | 
			
		||||
          npm run lint:types
 | 
			
		||||
      - name: Lint Web
 | 
			
		||||
        run: npm run ${{ matrix.command }} -w @goauthentik/web
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: web/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: web/package-lock.json
 | 
			
		||||
      - working-directory: web/
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - name: Generate TypeScript API
 | 
			
		||||
        run: make gen-client-ts
 | 
			
		||||
      - name: build
 | 
			
		||||
        working-directory: web/
 | 
			
		||||
        run: npm run build
 | 
			
		||||
        run: npm run build -w @goauthentik/web
 | 
			
		||||
  ci-web-mark:
 | 
			
		||||
    if: always()
 | 
			
		||||
    needs:
 | 
			
		||||
@ -78,13 +76,12 @@ jobs:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: web/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: web/package-lock.json
 | 
			
		||||
      - working-directory: web/
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - name: Generate TypeScript API
 | 
			
		||||
        run: make gen-client-ts
 | 
			
		||||
      - name: test
 | 
			
		||||
        working-directory: web/
 | 
			
		||||
        run: npm run test || exit 0
 | 
			
		||||
        run: npm run test -w @goauthentik/web || exit 0
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								.github/workflows/ci-website.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/ci-website.yml
									
									
									
									
										vendored
									
									
								
							@ -14,53 +14,44 @@ on:
 | 
			
		||||
jobs:
 | 
			
		||||
  lint:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        command:
 | 
			
		||||
          - lint:lockfile
 | 
			
		||||
          - prettier-check
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - working-directory: website/
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: Lint
 | 
			
		||||
        working-directory: website/
 | 
			
		||||
        run: npm run ${{ matrix.command }}
 | 
			
		||||
        run: npm run prettier-check -w @goauthentik/docs
 | 
			
		||||
  test:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: website/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: website/package-lock.json
 | 
			
		||||
      - working-directory: website/
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: test
 | 
			
		||||
        working-directory: website/
 | 
			
		||||
        run: npm test
 | 
			
		||||
        run: npm test -w @goauthentik/docs
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    name: ${{ matrix.job }}
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        job:
 | 
			
		||||
          - build
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: website/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: website/package-lock.json
 | 
			
		||||
      - working-directory: website/
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: build
 | 
			
		||||
        working-directory: website/
 | 
			
		||||
        run: npm run ${{ matrix.job }}
 | 
			
		||||
      - name: Run Docusaurus
 | 
			
		||||
        run: npm run build -w @goauthentik/docs
 | 
			
		||||
  ci-website-mark:
 | 
			
		||||
    if: always()
 | 
			
		||||
    needs:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								.github/workflows/packages-npm-publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.github/workflows/packages-npm-publish.yml
									
									
									
									
										vendored
									
									
								
							@ -17,27 +17,28 @@ jobs:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        package:
 | 
			
		||||
          - docusaurus-config
 | 
			
		||||
          - eslint-config
 | 
			
		||||
          - prettier-config
 | 
			
		||||
          - tsconfig
 | 
			
		||||
          - packages/docusaurus-config
 | 
			
		||||
          - packages/eslint-config
 | 
			
		||||
          - packages/prettier-config
 | 
			
		||||
          - packages/tsconfig
 | 
			
		||||
          - packages/web/esbuild-plugin-live-reload
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 2
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: packages/${{ matrix.package }}/package.json
 | 
			
		||||
          node-version-file: ${{ matrix.package }}/package.json
 | 
			
		||||
          registry-url: "https://registry.npmjs.org"
 | 
			
		||||
      - name: Get changed files
 | 
			
		||||
        id: changed-files
 | 
			
		||||
        uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
 | 
			
		||||
        with:
 | 
			
		||||
          files: |
 | 
			
		||||
            packages/${{ matrix.package }}/package.json
 | 
			
		||||
            ${{ matrix.package }}/package.json
 | 
			
		||||
      - name: Publish package
 | 
			
		||||
        if: steps.changed-files.outputs.any_changed == 'true'
 | 
			
		||||
        working-directory: packages/${{ matrix.package}}
 | 
			
		||||
        working-directory: ${{ matrix.package }}
 | 
			
		||||
        run: |
 | 
			
		||||
          npm ci
 | 
			
		||||
          npm run build
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
								
							@ -106,14 +106,14 @@ jobs:
 | 
			
		||||
          go-version-file: "go.mod"
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: web/package.json
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: web/package-lock.json
 | 
			
		||||
      - name: Build web
 | 
			
		||||
        working-directory: web/
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: Run ESBuild (Proxy)
 | 
			
		||||
        run: |
 | 
			
		||||
          npm ci
 | 
			
		||||
          npm run build-proxy
 | 
			
		||||
          npm run build-proxy -w @goauthentik/web
 | 
			
		||||
      - name: Build outpost
 | 
			
		||||
        run: |
 | 
			
		||||
          set -x
 | 
			
		||||
 | 
			
		||||
@ -32,15 +32,25 @@ jobs:
 | 
			
		||||
        if: ${{ github.event_name == 'pull_request' }}
 | 
			
		||||
      - name: Setup authentik env
 | 
			
		||||
        uses: ./.github/actions/setup
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: package.json
 | 
			
		||||
          cache: "npm"
 | 
			
		||||
          cache-dependency-path: package-lock.json
 | 
			
		||||
      - name: Prepare Dependencies
 | 
			
		||||
        run: npm ci
 | 
			
		||||
      - name: Generate TypeScript API
 | 
			
		||||
        run: make gen-client-ts
 | 
			
		||||
      - name: run extract
 | 
			
		||||
      - name: Run extract
 | 
			
		||||
        run: |
 | 
			
		||||
          uv run make i18n-extract
 | 
			
		||||
      - name: run compile
 | 
			
		||||
      - name: Run UV compile
 | 
			
		||||
        run: |
 | 
			
		||||
          uv run ak compilemessages
 | 
			
		||||
          make web-check-compile
 | 
			
		||||
      - name: Lint Project
 | 
			
		||||
        run: |
 | 
			
		||||
          npm run build-locales -w @goauthentik/web
 | 
			
		||||
          npm run lint:types
 | 
			
		||||
      - name: Create Pull Request
 | 
			
		||||
        if: ${{ github.event_name != 'pull_request' }}
 | 
			
		||||
        uses: peter-evans/create-pull-request@v7
 | 
			
		||||
 | 
			
		||||
@ -36,12 +36,19 @@ coverage
 | 
			
		||||
*.mdx
 | 
			
		||||
*.md
 | 
			
		||||
 | 
			
		||||
## Import order matters
 | 
			
		||||
poly.ts
 | 
			
		||||
src/locale-codes.ts
 | 
			
		||||
src/locales/
 | 
			
		||||
 | 
			
		||||
# Storybook
 | 
			
		||||
storybook-static/
 | 
			
		||||
.storybook/css-import-maps*
 | 
			
		||||
 | 
			
		||||
# JSON Schemas
 | 
			
		||||
schemas/**/*.json
 | 
			
		||||
blueprints/**/*.json
 | 
			
		||||
authentik/**/*.json
 | 
			
		||||
lifecycle/**/*.json
 | 
			
		||||
 | 
			
		||||
# Locales
 | 
			
		||||
web/src/locale-codes.ts
 | 
			
		||||
web/src/locales/
 | 
			
		||||
 | 
			
		||||
# Wireit's cache
 | 
			
		||||
.wireit
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							@ -17,6 +17,6 @@
 | 
			
		||||
        "ms-python.vscode-pylance",
 | 
			
		||||
        "redhat.vscode-yaml",
 | 
			
		||||
        "Tobermory.es6-string-html",
 | 
			
		||||
        "unifiedjs.vscode-mdx",
 | 
			
		||||
        "unifiedjs.vscode-mdx"
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							@ -4,12 +4,7 @@
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/core: make",
 | 
			
		||||
            "command": "uv",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "run",
 | 
			
		||||
                "make",
 | 
			
		||||
                "lint-fix",
 | 
			
		||||
                "lint"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["run", "make", "lint-fix", "lint"],
 | 
			
		||||
            "presentation": {
 | 
			
		||||
                "panel": "new"
 | 
			
		||||
            },
 | 
			
		||||
@ -18,11 +13,7 @@
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/core: run",
 | 
			
		||||
            "command": "uv",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "run",
 | 
			
		||||
                "ak",
 | 
			
		||||
                "server"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["run", "ak", "server"],
 | 
			
		||||
            "group": "build",
 | 
			
		||||
            "presentation": {
 | 
			
		||||
                "panel": "dedicated",
 | 
			
		||||
@ -32,17 +23,13 @@
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/web: make",
 | 
			
		||||
            "command": "make",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "web"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["web"],
 | 
			
		||||
            "group": "build"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/web: watch",
 | 
			
		||||
            "command": "make",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "web-watch"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["web-watch"],
 | 
			
		||||
            "group": "build",
 | 
			
		||||
            "presentation": {
 | 
			
		||||
                "panel": "dedicated",
 | 
			
		||||
@ -52,26 +39,19 @@
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik: install",
 | 
			
		||||
            "command": "make",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "install",
 | 
			
		||||
                "-j4"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["install", "-j4"],
 | 
			
		||||
            "group": "build"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/website: make",
 | 
			
		||||
            "command": "make",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "website"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["website"],
 | 
			
		||||
            "group": "build"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/website: watch",
 | 
			
		||||
            "command": "make",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "website-watch"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["website-watch"],
 | 
			
		||||
            "group": "build",
 | 
			
		||||
            "presentation": {
 | 
			
		||||
                "panel": "dedicated",
 | 
			
		||||
@ -81,11 +61,7 @@
 | 
			
		||||
        {
 | 
			
		||||
            "label": "authentik/api: generate",
 | 
			
		||||
            "command": "uv",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "run",
 | 
			
		||||
                "make",
 | 
			
		||||
                "gen"
 | 
			
		||||
            ],
 | 
			
		||||
            "args": ["run", "make", "gen"],
 | 
			
		||||
            "group": "build"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										80
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								Dockerfile
									
									
									
									
									
								
							@ -1,49 +1,41 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
 | 
			
		||||
# Stage 1: Build website
 | 
			
		||||
FROM --platform=${BUILDPLATFORM} docker.io/library/node:24 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:24 AS web-builder
 | 
			
		||||
# Stage 1: Build Node packages
 | 
			
		||||
FROM --platform=${BUILDPLATFORM} docker.io/library/node:24-slim AS node-packages
 | 
			
		||||
 | 
			
		||||
ARG GIT_BUILD_HASH
 | 
			
		||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
 | 
			
		||||
ENV NODE_ENV=production
 | 
			
		||||
 | 
			
		||||
WORKDIR /work/web
 | 
			
		||||
 | 
			
		||||
RUN --mount=type=bind,target=/work/web/package.json,src=./web/package.json \
 | 
			
		||||
    --mount=type=bind,target=/work/web/package-lock.json,src=./web/package-lock.json \
 | 
			
		||||
    --mount=type=bind,target=/work/web/packages/sfe/package.json,src=./web/packages/sfe/package.json \
 | 
			
		||||
    --mount=type=bind,target=/work/web/scripts,src=./web/scripts \
 | 
			
		||||
    --mount=type=cache,id=npm-web,sharing=shared,target=/root/.npm \
 | 
			
		||||
    npm ci --include=dev
 | 
			
		||||
WORKDIR /work
 | 
			
		||||
 | 
			
		||||
COPY ./SECURITY.md /work
 | 
			
		||||
COPY ./schema.yml /work
 | 
			
		||||
COPY ./docker-compose.yml /work
 | 
			
		||||
COPY ./blueprints /work/blueprints/
 | 
			
		||||
COPY ./package.json /work
 | 
			
		||||
COPY ./package-lock.json /work
 | 
			
		||||
COPY ./tsconfig.json /work
 | 
			
		||||
COPY ./packages/ /work/packages/
 | 
			
		||||
COPY ./web /work/web/
 | 
			
		||||
COPY ./website /work/website/
 | 
			
		||||
COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
 | 
			
		||||
COPY ./gen-ts-api /work/gen-ts-api/
 | 
			
		||||
 | 
			
		||||
RUN npm run build && \
 | 
			
		||||
    npm run build:sfe
 | 
			
		||||
RUN --mount=type=cache,id=npm-node,sharing=shared,target=/root/.npm \
 | 
			
		||||
    npm ci
 | 
			
		||||
 | 
			
		||||
# Stage 3: Build go proxy
 | 
			
		||||
RUN cd ./gen-ts-api && npm link
 | 
			
		||||
 | 
			
		||||
RUN npm link @goauthentik/api -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
ENV NODE_ENV=production
 | 
			
		||||
 | 
			
		||||
RUN npm run build -w @goauthentik/web
 | 
			
		||||
RUN npm run build -w @goauthentik/web-sfe
 | 
			
		||||
 | 
			
		||||
RUN npm run build:api -w @goauthentik/docs
 | 
			
		||||
RUN npm run build:docusaurus -w @goauthentik/docs
 | 
			
		||||
 | 
			
		||||
# Stage 2: Build go proxy
 | 
			
		||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS go-builder
 | 
			
		||||
 | 
			
		||||
ARG TARGETOS
 | 
			
		||||
@ -68,8 +60,8 @@ RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
 | 
			
		||||
COPY ./cmd /go/src/goauthentik.io/cmd
 | 
			
		||||
COPY ./authentik/lib /go/src/goauthentik.io/authentik/lib
 | 
			
		||||
COPY ./web/static.go /go/src/goauthentik.io/web/static.go
 | 
			
		||||
COPY --from=web-builder /work/web/robots.txt /go/src/goauthentik.io/web/robots.txt
 | 
			
		||||
COPY --from=web-builder /work/web/security.txt /go/src/goauthentik.io/web/security.txt
 | 
			
		||||
COPY --from=node-packages /work/web/robots.txt /go/src/goauthentik.io/web/robots.txt
 | 
			
		||||
COPY --from=node-packages /work/web/security.txt /go/src/goauthentik.io/web/security.txt
 | 
			
		||||
COPY ./internal /go/src/goauthentik.io/internal
 | 
			
		||||
COPY ./go.mod /go/src/goauthentik.io/go.mod
 | 
			
		||||
COPY ./go.sum /go/src/goauthentik.io/go.sum
 | 
			
		||||
@ -80,7 +72,7 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
 | 
			
		||||
    CGO_ENABLED=1 GOFIPS140=latest GOARM="${TARGETVARIANT#v}" \
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
 | 
			
		||||
@ -93,9 +85,9 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
 | 
			
		||||
    mkdir -p /usr/share/GeoIP && \
 | 
			
		||||
    /bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /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.7.6 AS uv
 | 
			
		||||
# Stage 6: Base python image
 | 
			
		||||
# Stage 5: Base python image
 | 
			
		||||
FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base
 | 
			
		||||
 | 
			
		||||
ENV VENV_PATH="/ak-root/.venv" \
 | 
			
		||||
@ -109,7 +101,7 @@ WORKDIR /ak-root/
 | 
			
		||||
 | 
			
		||||
COPY --from=uv /uv /uvx /bin/
 | 
			
		||||
 | 
			
		||||
# Stage 7: Python dependencies
 | 
			
		||||
# Stage 6: Python dependencies
 | 
			
		||||
FROM python-base AS python-deps
 | 
			
		||||
 | 
			
		||||
ARG TARGETARCH
 | 
			
		||||
@ -144,7 +136,7 @@ RUN --mount=type=bind,target=pyproject.toml,src=pyproject.toml \
 | 
			
		||||
    --mount=type=cache,target=/root/.cache/uv \
 | 
			
		||||
    uv sync --frozen --no-install-project --no-dev
 | 
			
		||||
 | 
			
		||||
# Stage 8: Run
 | 
			
		||||
# Stage 7: Run
 | 
			
		||||
FROM python-base AS final-image
 | 
			
		||||
 | 
			
		||||
ARG VERSION
 | 
			
		||||
@ -187,9 +179,9 @@ COPY ./lifecycle/ /lifecycle
 | 
			
		||||
COPY ./authentik/sources/kerberos/krb5.conf /etc/krb5.conf
 | 
			
		||||
COPY --from=go-builder /go/authentik /bin/authentik
 | 
			
		||||
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/authentik/ /web/authentik/
 | 
			
		||||
COPY --from=website-builder /work/website/build/ /website/help/
 | 
			
		||||
COPY --from=node-packages /work/web/dist/ /web/dist/
 | 
			
		||||
COPY --from=node-packages /work/web/authentik/ /web/authentik/
 | 
			
		||||
COPY --from=node-packages /work/website/build/ /website/help/
 | 
			
		||||
COPY --from=geoip /usr/share/GeoIP /geoip
 | 
			
		||||
 | 
			
		||||
USER 1000
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								Makefile
									
									
									
									
									
								
							@ -73,7 +73,7 @@ core-i18n-extract:
 | 
			
		||||
		--ignore website \
 | 
			
		||||
		-l en
 | 
			
		||||
 | 
			
		||||
install: web-install website-install core-install  ## Install all requires dependencies for `web`, `website` and `core`
 | 
			
		||||
install: npm-install core-install  ## Install all requires dependencies for `web`, `website` and `core`
 | 
			
		||||
 | 
			
		||||
dev-drop-db:
 | 
			
		||||
	dropdb -U ${pg_user} -h ${pg_host} ${pg_name}
 | 
			
		||||
@ -146,9 +146,8 @@ gen-client-ts: gen-clean-ts  ## Build and install the authentik API for Typescri
 | 
			
		||||
		--additional-properties=npmVersion=${NPM_VERSION} \
 | 
			
		||||
		--git-repo-id authentik \
 | 
			
		||||
		--git-user-id goauthentik
 | 
			
		||||
	mkdir -p web/node_modules/@goauthentik/api
 | 
			
		||||
	cd ${PWD}/${GEN_API_TS} && npm i
 | 
			
		||||
	\cp -rf ${PWD}/${GEN_API_TS}/* web/node_modules/@goauthentik/api
 | 
			
		||||
	cd ./${GEN_API_TS} && npm link
 | 
			
		||||
	npm link @goauthentik/api -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
gen-client-py: gen-clean-py ## Build and install the authentik API for Python
 | 
			
		||||
	docker run \
 | 
			
		||||
@ -183,38 +182,34 @@ gen: gen-build gen-client-ts
 | 
			
		||||
## Web
 | 
			
		||||
#########################
 | 
			
		||||
 | 
			
		||||
web-build: web-install  ## Build the Authentik UI
 | 
			
		||||
	cd web && npm run build
 | 
			
		||||
web-build: npm-install  ## Build the Authentik UI
 | 
			
		||||
	npm run build -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
npm-install:  ## Install the necessary libraries to build the Authentik UI
 | 
			
		||||
	npm ci
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
	rm -rf web/dist/
 | 
			
		||||
	mkdir web/dist/
 | 
			
		||||
	touch web/dist/.gitkeep
 | 
			
		||||
	cd web && npm run watch
 | 
			
		||||
	npm run watch -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
web-storybook-watch:  ## Build and run the storybook documentation server
 | 
			
		||||
	cd web && npm run storybook
 | 
			
		||||
	npm run storybook -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
web-lint-fix:
 | 
			
		||||
	cd web && npm run prettier
 | 
			
		||||
	npm run prettier -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
web-lint:
 | 
			
		||||
	cd web && npm run lint
 | 
			
		||||
	cd web && npm run lit-analyse
 | 
			
		||||
	npm run lint -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
web-check-compile:
 | 
			
		||||
	cd web && npm run tsc
 | 
			
		||||
	npm run lint:types
 | 
			
		||||
 | 
			
		||||
web-i18n-extract:
 | 
			
		||||
	cd web && npm run extract-locales
 | 
			
		||||
	npm run extract-locales -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
#########################
 | 
			
		||||
## Website
 | 
			
		||||
@ -222,17 +217,14 @@ web-i18n-extract:
 | 
			
		||||
 | 
			
		||||
website: website-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
 | 
			
		||||
	npm run prettier --prefix website
 | 
			
		||||
 | 
			
		||||
website-build:
 | 
			
		||||
	cd website && npm run build
 | 
			
		||||
	npm run build --prefix website
 | 
			
		||||
 | 
			
		||||
website-watch:  ## Build and watch the documentation website, updating automatically
 | 
			
		||||
	cd website && npm run watch
 | 
			
		||||
	npm run watch --prefix website
 | 
			
		||||
 | 
			
		||||
#########################
 | 
			
		||||
## Docker
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
							
								
								
									
										44361
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										44361
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										29
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								package.json
									
									
									
									
									
								
							@ -2,14 +2,33 @@
 | 
			
		||||
    "name": "@goauthentik/authentik",
 | 
			
		||||
    "version": "2025.4.1",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "lint": "eslint --fix .",
 | 
			
		||||
        "lint-check": "eslint --max-warnings 0 .",
 | 
			
		||||
        "lint:types": "NODE_OPTIONS=\"--max-old-space-size=3000\" tsc -b .",
 | 
			
		||||
        "prettier": "prettier --cache --write -u .",
 | 
			
		||||
        "prettier-check": "prettier --cache --check -u ."
 | 
			
		||||
    },
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@eslint/js": "^9.11.1",
 | 
			
		||||
        "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "prettier-plugin-organize-imports": "^4.1.0",
 | 
			
		||||
        "prettier-plugin-packagejson": "^2.5.10",
 | 
			
		||||
        "typescript": "^5.6.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-packagejson": "^2.5.13",
 | 
			
		||||
        "typescript": "^5.8.3",
 | 
			
		||||
        "typescript-eslint": "^8.29.0"
 | 
			
		||||
    },
 | 
			
		||||
    "workspaces": [],
 | 
			
		||||
    "workspaces": [
 | 
			
		||||
        "./packages/*",
 | 
			
		||||
        "./web/packages/*",
 | 
			
		||||
        "./web",
 | 
			
		||||
        "./website"
 | 
			
		||||
    ],
 | 
			
		||||
    "prettier": "./packages/prettier-config/index.js"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@ export const DefaultIgnorePatterns = [
 | 
			
		||||
    "**/out",
 | 
			
		||||
    "**/dist",
 | 
			
		||||
    "**/.wireit",
 | 
			
		||||
    "**/.venv",
 | 
			
		||||
    "website/build/**",
 | 
			
		||||
    "website/.docusaurus/**",
 | 
			
		||||
    "**/node_modules",
 | 
			
		||||
@ -58,16 +59,44 @@ export function createESLintPackageConfig({ ignorePatterns = DefaultIgnorePatter
 | 
			
		||||
 | 
			
		||||
        ...reactConfig,
 | 
			
		||||
 | 
			
		||||
        //#region TODO Incomplete Rules
 | 
			
		||||
        {
 | 
			
		||||
            // The following rules are disabled because the changes needed to satisfy them are
 | 
			
		||||
            // are large enough to warrant several follow-up PRs.
 | 
			
		||||
            rules: {
 | 
			
		||||
                "no-console": "off",
 | 
			
		||||
                // TODO: High priority, common and easy to fix.
 | 
			
		||||
                "eqeqeq": "off",
 | 
			
		||||
                // TODO: High priority, common and easy to fix.
 | 
			
		||||
                "no-sparse-arrays": "off",
 | 
			
		||||
                // TODO: High priority, common and easy to fix.
 | 
			
		||||
                "no-lonely-if": "off",
 | 
			
		||||
                // TODO: Reconsider this rule.
 | 
			
		||||
                "dot-notation": "off",
 | 
			
		||||
                // TODO: Reconsider this rule.
 | 
			
		||||
                "no-implicit-coercion": "off",
 | 
			
		||||
                // TODO: Reconsider this rule.
 | 
			
		||||
                "prefer-template": "off",
 | 
			
		||||
                "@typescript-eslint/ban-ts-comment": "off",
 | 
			
		||||
                "@typescript-eslint/no-unused-vars": "off",
 | 
			
		||||
                "@typescript-eslint/no-use-before-define": "off",
 | 
			
		||||
                "array-callback-return": "off",
 | 
			
		||||
                "block-scoped-var": "off",
 | 
			
		||||
                "consistent-return": "off",
 | 
			
		||||
                "func-names": "off",
 | 
			
		||||
                "guard-for-in": "off",
 | 
			
		||||
                "no-bitwise": "off",
 | 
			
		||||
                "no-div-regex": "off",
 | 
			
		||||
                "no-else-return": "off",
 | 
			
		||||
                "no-empty-function": "off",
 | 
			
		||||
                "no-param-reassign": "off",
 | 
			
		||||
                "no-throw-literal": "off",
 | 
			
		||||
                "no-var": "error",
 | 
			
		||||
                "prefer-arrow-callback": "off",
 | 
			
		||||
                "react/jsx-no-leaked-render": "off",
 | 
			
		||||
                "vars-on-top": "off",
 | 
			
		||||
            },
 | 
			
		||||
            files: [
 | 
			
		||||
                // ---
 | 
			
		||||
                "**/scripts/**/*",
 | 
			
		||||
                "**/test/**/*",
 | 
			
		||||
                "**/tests/**/*",
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        //#endregion
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -116,7 +116,6 @@ export const javaScriptConfig = tseslint.config({
 | 
			
		||||
        "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",
 | 
			
		||||
@ -131,7 +130,6 @@ export const javaScriptConfig = tseslint.config({
 | 
			
		||||
        "vars-on-top": "error",
 | 
			
		||||
        "yoda": ["error", "never"],
 | 
			
		||||
 | 
			
		||||
        "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],
 | 
			
		||||
 | 
			
		||||
@ -2,19 +2,19 @@
 | 
			
		||||
    "name": "@goauthentik/tsconfig",
 | 
			
		||||
    "version": "1.0.4",
 | 
			
		||||
    "description": "authentik's base TypeScript configuration.",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "tsconfig",
 | 
			
		||||
        "typescript"
 | 
			
		||||
    ],
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": ""
 | 
			
		||||
    },
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "main": "tsconfig.json",
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20.11"
 | 
			
		||||
    },
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "tsconfig",
 | 
			
		||||
        "typescript"
 | 
			
		||||
    ],
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,22 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
 | 
			
		||||
# Stage 1: Build web
 | 
			
		||||
FROM --platform=${BUILDPLATFORM} docker.io/library/node:24 AS web-builder
 | 
			
		||||
FROM --platform=${BUILDPLATFORM} docker.io/library/node:24-slim AS web-builder
 | 
			
		||||
 | 
			
		||||
WORKDIR /work
 | 
			
		||||
 | 
			
		||||
COPY ./package.json /work
 | 
			
		||||
COPY ./package-lock.json /work
 | 
			
		||||
COPY ./tsconfig.json /work
 | 
			
		||||
COPY ./packages/ /work/packages/
 | 
			
		||||
COPY ./web /work/web/
 | 
			
		||||
 | 
			
		||||
RUN --mount=type=cache,id=npm-node,sharing=shared,target=/root/.npm \
 | 
			
		||||
    npm ci
 | 
			
		||||
 | 
			
		||||
ENV NODE_ENV=production
 | 
			
		||||
WORKDIR /static
 | 
			
		||||
 | 
			
		||||
COPY package.json /
 | 
			
		||||
RUN --mount=type=bind,target=/static/package.json,src=./web/package.json \
 | 
			
		||||
    --mount=type=bind,target=/static/package-lock.json,src=./web/package-lock.json \
 | 
			
		||||
    --mount=type=bind,target=/static/scripts,src=./web/scripts \
 | 
			
		||||
    --mount=type=cache,target=/root/.npm \
 | 
			
		||||
    npm ci --include=dev
 | 
			
		||||
 | 
			
		||||
COPY web .
 | 
			
		||||
RUN npm run build-proxy
 | 
			
		||||
RUN npm run build-proxy -w @goauthentik/web
 | 
			
		||||
 | 
			
		||||
# Stage 2: Build
 | 
			
		||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS builder
 | 
			
		||||
@ -65,10 +67,10 @@ RUN apt-get update && \
 | 
			
		||||
    rm -rf /tmp/* /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
COPY --from=builder /go/proxy /
 | 
			
		||||
COPY --from=web-builder /static/robots.txt /web/robots.txt
 | 
			
		||||
COPY --from=web-builder /static/security.txt /web/security.txt
 | 
			
		||||
COPY --from=web-builder /static/dist/ /web/dist/
 | 
			
		||||
COPY --from=web-builder /static/authentik/ /web/authentik/
 | 
			
		||||
COPY --from=web-builder /work/web/robots.txt /web/robots.txt
 | 
			
		||||
COPY --from=web-builder /work/web/security.txt /web/security.txt
 | 
			
		||||
COPY --from=web-builder /work/web/dist/ /web/dist/
 | 
			
		||||
COPY --from=web-builder /work/web/authentik/ /web/authentik/
 | 
			
		||||
 | 
			
		||||
HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/proxy", "healthcheck" ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								scripts/api-ts-templates/tsconfig.esm.mustache
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								scripts/api-ts-templates/tsconfig.esm.mustache
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "$schema": "https://json.schemastore.org/tsconfig",
 | 
			
		||||
    "extends": "./tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "outDir": "dist/esm",
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								scripts/api-ts-templates/tsconfig.mustache
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								scripts/api-ts-templates/tsconfig.mustache
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
{
 | 
			
		||||
    "$schema": "https://json.schemastore.org/tsconfig",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "composite": true,
 | 
			
		||||
        "isolatedModules": true,
 | 
			
		||||
        "incremental": true,
 | 
			
		||||
        "baseUrl": ".",
 | 
			
		||||
        "rootDir": "src",
 | 
			
		||||
        "strict": true,
 | 
			
		||||
        "newLine": "lf",
 | 
			
		||||
        "target": "ESNext",
 | 
			
		||||
        "module": "ESNext",
 | 
			
		||||
        "moduleResolution": "bundler",
 | 
			
		||||
        "outDir": "dist",
 | 
			
		||||
        "skipDefaultLibCheck": true,
 | 
			
		||||
        "skipLibCheck": true,
 | 
			
		||||
        "sourceMap": true,
 | 
			
		||||
        "declaration": true,
 | 
			
		||||
        "declarationMap": true,
 | 
			
		||||
        "lib": ["DOM", "DOM.Iterable", "ESNext"],
 | 
			
		||||
    },
 | 
			
		||||
    "exclude": ["node_modules", "./out/**/*", "./dist/**/*"],
 | 
			
		||||
}
 | 
			
		||||
@ -23,6 +23,8 @@
 | 
			
		||||
    "files": [],
 | 
			
		||||
    "references": [
 | 
			
		||||
        // Note that references are in the order we want them to be built.
 | 
			
		||||
        // TODO: Left blank until TypeScript workspaces are complete.
 | 
			
		||||
        {
 | 
			
		||||
            "path": "./web"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								web/commands.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								web/commands.mjs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
/// <reference types="@wdio/globals/types" />
 | 
			
		||||
/// <reference types="./types/webdriver.js" />
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @param {WebdriverIO.Browser} browser
 | 
			
		||||
 */
 | 
			
		||||
export function addCommands(browser) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @file Custom WDIO browser commands
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    browser.addCommand(
 | 
			
		||||
        "focus",
 | 
			
		||||
        /**
 | 
			
		||||
         * @this {HTMLElement}
 | 
			
		||||
         */
 | 
			
		||||
        function () {
 | 
			
		||||
            this.focus();
 | 
			
		||||
 | 
			
		||||
            return this;
 | 
			
		||||
        },
 | 
			
		||||
        /* attachToElement */ true,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    browser.addCommand(
 | 
			
		||||
        "blur",
 | 
			
		||||
        /**
 | 
			
		||||
         * @this {HTMLElement}
 | 
			
		||||
         */
 | 
			
		||||
        function () {
 | 
			
		||||
            this.blur();
 | 
			
		||||
 | 
			
		||||
            return this;
 | 
			
		||||
        },
 | 
			
		||||
        /* attachToElement */ true,
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
@ -24,13 +24,12 @@ export default tseslint.config(
 | 
			
		||||
    ...ESLintConfig,
 | 
			
		||||
    {
 | 
			
		||||
        rules: {
 | 
			
		||||
            "no-console": "off",
 | 
			
		||||
            "no-console": ["error", { allow: ["debug", "warn", "error"] }],
 | 
			
		||||
        },
 | 
			
		||||
        files: ["packages/**/*"],
 | 
			
		||||
        files: ["src/**/*"],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        rules: {
 | 
			
		||||
            "no-void": "off",
 | 
			
		||||
            "no-implicit-coercion": "off",
 | 
			
		||||
            "prefer-template": "off",
 | 
			
		||||
            "@typescript-eslint/ban-ts-comment": "off",
 | 
			
		||||
@ -47,7 +46,6 @@ export default tseslint.config(
 | 
			
		||||
            "no-empty-function": "off",
 | 
			
		||||
            "no-param-reassign": "off",
 | 
			
		||||
            "no-throw-literal": "off",
 | 
			
		||||
            // "no-var": "off",
 | 
			
		||||
            "prefer-arrow-callback": "off",
 | 
			
		||||
            "react/jsx-no-leaked-render": "off",
 | 
			
		||||
            "vars-on-top": "off",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27188
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27188
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -14,13 +14,13 @@
 | 
			
		||||
        "format": "wireit",
 | 
			
		||||
        "lint": "eslint --fix .",
 | 
			
		||||
        "lint-check": "eslint --max-warnings 0 .",
 | 
			
		||||
        "prettier": "prettier --cache --write -u .",
 | 
			
		||||
        "prettier-check": "prettier --cache --check -u .",
 | 
			
		||||
        "lint:imports": "knip --config scripts/knip.config.ts",
 | 
			
		||||
        "lint:lockfile": "wireit",
 | 
			
		||||
        "lint:types": "wireit",
 | 
			
		||||
        "lit-analyse": "wireit",
 | 
			
		||||
        "precommit": "wireit",
 | 
			
		||||
        "prettier": "prettier --cache --write -u .",
 | 
			
		||||
        "prettier-check": "prettier --cache --check -u .",
 | 
			
		||||
        "pseudolocalize": "node ./scripts/pseudolocalize.mjs",
 | 
			
		||||
        "storybook": "storybook dev -p 6006",
 | 
			
		||||
        "storybook:build": "wireit",
 | 
			
		||||
@ -143,8 +143,8 @@
 | 
			
		||||
        "@eslint/js": "^9.27.0",
 | 
			
		||||
        "@goauthentik/core": "^1.0.0",
 | 
			
		||||
        "@goauthentik/esbuild-plugin-live-reload": "^1.0.4",
 | 
			
		||||
        "@goauthentik/eslint-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/eslint-config": "^1.0.5",
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.5",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@hcaptcha/types": "^1.0.4",
 | 
			
		||||
        "@lit/localize-tools": "^0.8.0",
 | 
			
		||||
@ -168,9 +168,10 @@
 | 
			
		||||
        "@types/react-dom": "^19.1.5",
 | 
			
		||||
        "@typescript-eslint/eslint-plugin": "^8.8.0",
 | 
			
		||||
        "@typescript-eslint/parser": "^8.8.0",
 | 
			
		||||
        "@wdio/browser-runner": "9.4",
 | 
			
		||||
        "@wdio/cli": "9.4",
 | 
			
		||||
        "@wdio/spec-reporter": "^9.1.2",
 | 
			
		||||
        "@wdio/browser-runner": "^9.14.0",
 | 
			
		||||
        "@wdio/cli": "^9.14.0",
 | 
			
		||||
        "@wdio/spec-reporter": "^9.14.0",
 | 
			
		||||
        "@web/test-runner": "^0.20.2",
 | 
			
		||||
        "chromedriver": "^136.0.3",
 | 
			
		||||
        "esbuild": "^0.25.4",
 | 
			
		||||
        "esbuild-plugin-copy": "^2.1.1",
 | 
			
		||||
@ -184,7 +185,7 @@
 | 
			
		||||
        "knip": "^5.30.6",
 | 
			
		||||
        "lit-analyzer": "^2.0.3",
 | 
			
		||||
        "npm-run-all": "^4.1.5",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "prettier": "^3.5.3",
 | 
			
		||||
        "pseudolocale": "^2.1.0",
 | 
			
		||||
        "rollup-plugin-postcss-lit": "^2.2.0",
 | 
			
		||||
        "storybook": "^8.6.14",
 | 
			
		||||
@ -301,8 +302,7 @@
 | 
			
		||||
                "lint",
 | 
			
		||||
                "lint:types",
 | 
			
		||||
                "lint:components",
 | 
			
		||||
                "lint:lockfile",
 | 
			
		||||
                "lint:lockfiles"
 | 
			
		||||
                "lint:lockfile"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        "storybook:build": {
 | 
			
		||||
@ -371,12 +371,12 @@
 | 
			
		||||
        "chromedriver": {
 | 
			
		||||
            "axios": "^1.8.4"
 | 
			
		||||
        },
 | 
			
		||||
        "rapidoc": {
 | 
			
		||||
            "@apitools/openapi-parser@": "0.0.37"
 | 
			
		||||
        },
 | 
			
		||||
        "storybook-addon-mock": {
 | 
			
		||||
            "react": "^19.1.0",
 | 
			
		||||
            "react-dom": "^19.1.0"
 | 
			
		||||
        },
 | 
			
		||||
        "rapidoc": {
 | 
			
		||||
            "@apitools/openapi-parser@": "0.0.37"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -48,8 +48,8 @@
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@types/node": "^22.15.21",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "typescript": "^5.6.3"
 | 
			
		||||
        "prettier": "^3.5.3",
 | 
			
		||||
        "typescript": "^5.8.3"
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20.11"
 | 
			
		||||
 | 
			
		||||
@ -10,52 +10,52 @@ const DOCS_DOMAIN = "https://goauthentik.io";
 | 
			
		||||
 * - Resolves relative links to the public directory in the public docs domain.
 | 
			
		||||
 * - Intercepts local links and scrolls to the target element.
 | 
			
		||||
 */
 | 
			
		||||
export const MDXAnchor = memo<React.AnchorHTMLAttributes<HTMLAnchorElement>>(
 | 
			
		||||
    ({ href, children, ...props }) => {
 | 
			
		||||
        const { publicDirectory } = useMDXModule();
 | 
			
		||||
export const MDXAnchor = ({
 | 
			
		||||
    href,
 | 
			
		||||
    children,
 | 
			
		||||
    ...props
 | 
			
		||||
}: React.AnchorHTMLAttributes<HTMLAnchorElement>) => {
 | 
			
		||||
    const { publicDirectory } = useMDXModule();
 | 
			
		||||
 | 
			
		||||
        if (href?.startsWith(".") && publicDirectory) {
 | 
			
		||||
            const nextPathname = resolve(publicDirectory, href);
 | 
			
		||||
    if (href?.startsWith(".") && publicDirectory) {
 | 
			
		||||
        const nextPathname = resolve(publicDirectory, href);
 | 
			
		||||
 | 
			
		||||
            const nextURL = new URL(nextPathname, DOCS_DOMAIN);
 | 
			
		||||
            // Remove trailing .md and .mdx, and trailing "index".
 | 
			
		||||
            nextURL.pathname = nextURL.pathname.replace(/(index)?\.mdx?$/, "");
 | 
			
		||||
            href = nextURL.toString();
 | 
			
		||||
        const nextURL = new URL(nextPathname, DOCS_DOMAIN);
 | 
			
		||||
        // Remove trailing .md and .mdx, and trailing "index".
 | 
			
		||||
        nextURL.pathname = nextURL.pathname.replace(/(index)?\.mdx?$/, "");
 | 
			
		||||
        href = nextURL.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const interceptHeadingLinks = (event: React.MouseEvent<HTMLAnchorElement>) => {
 | 
			
		||||
        if (!href || !href.startsWith("#")) return;
 | 
			
		||||
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
 | 
			
		||||
        const rootNode = event.currentTarget.getRootNode() as ShadowRoot;
 | 
			
		||||
 | 
			
		||||
        const elementID = href.slice(1);
 | 
			
		||||
        const target = rootNode.getElementById(elementID);
 | 
			
		||||
 | 
			
		||||
        if (!target) {
 | 
			
		||||
            console.warn(`Element with ID ${elementID} not found`);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const interceptHeadingLinks = (event: React.MouseEvent<HTMLAnchorElement>) => {
 | 
			
		||||
            if (!href || !href.startsWith("#")) return;
 | 
			
		||||
        target.scrollIntoView({
 | 
			
		||||
            behavior: "smooth",
 | 
			
		||||
            block: "center",
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            const rootNode = event.currentTarget.getRootNode() as ShadowRoot;
 | 
			
		||||
 | 
			
		||||
            const elementID = href.slice(1);
 | 
			
		||||
            const target = rootNode.getElementById(elementID);
 | 
			
		||||
 | 
			
		||||
            if (!target) {
 | 
			
		||||
                console.warn(`Element with ID ${elementID} not found`);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            target.scrollIntoView({
 | 
			
		||||
                behavior: "smooth",
 | 
			
		||||
                block: "center",
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return (
 | 
			
		||||
            <a
 | 
			
		||||
                href={href}
 | 
			
		||||
                onClick={interceptHeadingLinks}
 | 
			
		||||
                rel="noopener noreferrer"
 | 
			
		||||
                target="_blank"
 | 
			
		||||
                {...props}
 | 
			
		||||
            >
 | 
			
		||||
                {children}
 | 
			
		||||
            </a>
 | 
			
		||||
        );
 | 
			
		||||
    },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
MDXAnchor.displayName = "MDXAnchor";
 | 
			
		||||
    return (
 | 
			
		||||
        <a
 | 
			
		||||
            href={href}
 | 
			
		||||
            onClick={interceptHeadingLinks}
 | 
			
		||||
            rel="noopener noreferrer"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
            {...props}
 | 
			
		||||
        >
 | 
			
		||||
            {children}
 | 
			
		||||
        </a>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ export interface MDXWrapperProps {
 | 
			
		||||
/**
 | 
			
		||||
 * A wrapper component for MDX content that adds a title if one is provided in the frontmatter.
 | 
			
		||||
 */
 | 
			
		||||
export const MDXWrapper: React.FC<MDXWrapperProps> = ({ children, frontmatter }) => {
 | 
			
		||||
export const MDXWrapper = ({ children, frontmatter }: MDXWrapperProps) => {
 | 
			
		||||
    const { title } = frontmatter;
 | 
			
		||||
    const nextChildren = React.Children.toArray(children);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,12 +4,13 @@ import { Route } from "@goauthentik/elements/router/Route";
 | 
			
		||||
import { RouteMatch } from "@goauthentik/elements/router/RouteMatch";
 | 
			
		||||
import "@goauthentik/elements/router/Router404";
 | 
			
		||||
import {
 | 
			
		||||
    BrowserClient,
 | 
			
		||||
    SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
 | 
			
		||||
    Span,
 | 
			
		||||
    getClient,
 | 
			
		||||
    startBrowserTracingNavigationSpan,
 | 
			
		||||
    startBrowserTracingPageLoadSpan,
 | 
			
		||||
} from "@sentry/browser";
 | 
			
		||||
import { Client, Span } from "@sentry/types";
 | 
			
		||||
 | 
			
		||||
import { CSSResult, PropertyValues, TemplateResult, css, html } from "lit";
 | 
			
		||||
import { customElement, property } from "lit/decorators.js";
 | 
			
		||||
@ -60,7 +61,7 @@ export class RouterOutlet extends AKElement {
 | 
			
		||||
    @property({ attribute: false })
 | 
			
		||||
    routes: Route[] = [];
 | 
			
		||||
 | 
			
		||||
    private sentryClient?: Client;
 | 
			
		||||
    private sentryClient?: BrowserClient;
 | 
			
		||||
    private pageLoadSpan?: Span;
 | 
			
		||||
 | 
			
		||||
    static get styles(): CSSResult[] {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "strict": true,
 | 
			
		||||
        "baseUrl": ".",
 | 
			
		||||
        "moduleResolution": "node",
 | 
			
		||||
        "module": "ESNext",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										123
									
								
								web/tests/wdio.conf.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								web/tests/wdio.conf.mjs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,123 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file WebdriverIO configuration file for **component unit tests**.
 | 
			
		||||
 *
 | 
			
		||||
 * @see https://webdriver.io/docs/configurationfile.html
 | 
			
		||||
 */
 | 
			
		||||
import { cwd } from "process";
 | 
			
		||||
import litCSS from "vite-plugin-lit-css";
 | 
			
		||||
import tsconfigPaths from "vite-tsconfig-paths";
 | 
			
		||||
 | 
			
		||||
import { addCommands } from "../commands.mjs";
 | 
			
		||||
 | 
			
		||||
const NODE_ENV = process.env.NODE_ENV || "development";
 | 
			
		||||
const headless = !!process.env.HEADLESS || !!process.env.CI;
 | 
			
		||||
const lemmeSee = !!process.env.WDIO_LEMME_SEE;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @type {WebdriverIO.Capabilities[]}
 | 
			
		||||
 */
 | 
			
		||||
const capabilities = [];
 | 
			
		||||
 | 
			
		||||
const DEFAULT_MAX_INSTANCES = 10;
 | 
			
		||||
 | 
			
		||||
let maxInstances = 1;
 | 
			
		||||
 | 
			
		||||
if (headless) {
 | 
			
		||||
    maxInstances = process.env.MAX_INSTANCES
 | 
			
		||||
        ? parseInt(process.env.MAX_INSTANCES, 10)
 | 
			
		||||
        : DEFAULT_MAX_INSTANCES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!process.env.WDIO_SKIP_CHROME) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @satisfies {WebdriverIO.Capabilities}
 | 
			
		||||
     */
 | 
			
		||||
    const chromeBrowserConfig = {
 | 
			
		||||
        "browserName": "chrome",
 | 
			
		||||
        "goog:chromeOptions": {
 | 
			
		||||
            args: ["disable-search-engine-choice-screen"],
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (headless) {
 | 
			
		||||
        chromeBrowserConfig["goog:chromeOptions"].args.push(
 | 
			
		||||
            "headless",
 | 
			
		||||
            "disable-gpu",
 | 
			
		||||
            "no-sandbox",
 | 
			
		||||
            "window-size=1280,672",
 | 
			
		||||
            "browser-test",
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    capabilities.push(chromeBrowserConfig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.env.WDIO_TEST_SAFARI) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "safari",
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.env.WDIO_TEST_FIREFOX) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "firefox",
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @type {WebdriverIO.BrowserRunnerOptions}
 | 
			
		||||
 */
 | 
			
		||||
const browserRunnerOptions = {
 | 
			
		||||
    viteConfig: {
 | 
			
		||||
        define: {
 | 
			
		||||
            "process.env.NODE_ENV": JSON.stringify(NODE_ENV),
 | 
			
		||||
            "process.env.CWD": JSON.stringify(cwd()),
 | 
			
		||||
            "process.env.AK_API_BASE_PATH": JSON.stringify(process.env.AK_API_BASE_PATH || ""),
 | 
			
		||||
        },
 | 
			
		||||
        plugins: [
 | 
			
		||||
            // ---
 | 
			
		||||
            // @ts-ignore WDIO's Vite is out of date.
 | 
			
		||||
            litCSS(),
 | 
			
		||||
            // @ts-ignore WDIO's Vite is out of date.
 | 
			
		||||
            tsconfigPaths(),
 | 
			
		||||
        ],
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
/**
 | 
			
		||||
 * @satisfies {WebdriverIO.Config}
 | 
			
		||||
 */
 | 
			
		||||
export const config = {
 | 
			
		||||
    runner: ["browser", browserRunnerOptions],
 | 
			
		||||
 | 
			
		||||
    tsConfigPath: "./tsconfig.test.json",
 | 
			
		||||
 | 
			
		||||
    specs: ["./src/**/*.test.ts"],
 | 
			
		||||
    exclude: [],
 | 
			
		||||
 | 
			
		||||
    maxInstances,
 | 
			
		||||
    capabilities,
 | 
			
		||||
    logLevel: "warn",
 | 
			
		||||
    bail: 0,
 | 
			
		||||
    waitforTimeout: 12000,
 | 
			
		||||
    connectionRetryTimeout: 12000,
 | 
			
		||||
    connectionRetryCount: 3,
 | 
			
		||||
 | 
			
		||||
    framework: "mocha",
 | 
			
		||||
 | 
			
		||||
    reporters: ["spec"],
 | 
			
		||||
 | 
			
		||||
    mochaOpts: {
 | 
			
		||||
        ui: "bdd",
 | 
			
		||||
        timeout: 60000,
 | 
			
		||||
    },
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {WebdriverIO.Browser} browser
 | 
			
		||||
     */
 | 
			
		||||
    before(_capabilities, _specs, browser) {
 | 
			
		||||
        addCommands(browser);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    afterTest() {
 | 
			
		||||
        if (lemmeSee) return browser.pause(500);
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@ -1,320 +0,0 @@
 | 
			
		||||
import { browser } from "@wdio/globals";
 | 
			
		||||
 | 
			
		||||
const lemmeSee = process.env.WDIO_LEMME_SEE !== undefined;
 | 
			
		||||
 | 
			
		||||
const testSafari = process.env.WDIO_TEST_SAFARI !== undefined;
 | 
			
		||||
const testFirefox = process.env.WDIO_TEST_FIREFOX !== undefined;
 | 
			
		||||
const skipChrome = process.env.WDIO_SKIP_CHROME !== undefined;
 | 
			
		||||
const runHeadless = process.env.CI !== undefined;
 | 
			
		||||
 | 
			
		||||
const capabilities = [];
 | 
			
		||||
 | 
			
		||||
if (!skipChrome) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        "browserName": "chrome",
 | 
			
		||||
        "wdio:chromedriverOptions": {
 | 
			
		||||
            binary: "./node_modules/.bin/chromedriver",
 | 
			
		||||
        },
 | 
			
		||||
        "goog:chromeOptions": {
 | 
			
		||||
            args: ["disable-infobars", "window-size=1280,800"].concat(
 | 
			
		||||
                (function () {
 | 
			
		||||
                    return runHeadless
 | 
			
		||||
                        ? [
 | 
			
		||||
                              "headless",
 | 
			
		||||
                              "no-sandbox",
 | 
			
		||||
                              "disable-gpu",
 | 
			
		||||
                              "disable-setuid-sandbox",
 | 
			
		||||
                              "disable-dev-shm-usage",
 | 
			
		||||
                          ]
 | 
			
		||||
                        : [];
 | 
			
		||||
                })(),
 | 
			
		||||
            ),
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (testSafari) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "safari", // or "firefox", "microsoftedge", "safari"
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (testFirefox) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "firefox", // or "firefox", "microsoftedge", "safari"
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const config: WebdriverIO.Config = {
 | 
			
		||||
    //
 | 
			
		||||
    // ====================
 | 
			
		||||
    // Runner Configuration
 | 
			
		||||
    // ====================
 | 
			
		||||
    // WebdriverIO supports running e2e tests as well as unit and component tests.
 | 
			
		||||
    runner: "local",
 | 
			
		||||
    tsConfigPath: "./tsconfig.json",
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // ==================
 | 
			
		||||
    // Specify Test Files
 | 
			
		||||
    // ==================
 | 
			
		||||
    // Define which test specs should run. The pattern is relative to the directory
 | 
			
		||||
    // of the configuration file being run.
 | 
			
		||||
    //
 | 
			
		||||
    // The specs are defined as an array of spec files (optionally using wildcards
 | 
			
		||||
    // that will be expanded). The test for each spec file will be run in a separate
 | 
			
		||||
    // worker process. In order to have a group of spec files run in the same worker
 | 
			
		||||
    // process simply enclose them in an array within the specs array.
 | 
			
		||||
    //
 | 
			
		||||
    // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script),
 | 
			
		||||
    // then the current working directory is where your `package.json` resides, so `wdio`
 | 
			
		||||
    // will be called from there.
 | 
			
		||||
    //
 | 
			
		||||
    specs: ["./specs/**/*.ts"],
 | 
			
		||||
    // Patterns to exclude.
 | 
			
		||||
    exclude: [
 | 
			
		||||
        // 'path/to/excluded/files'
 | 
			
		||||
    ],
 | 
			
		||||
    //
 | 
			
		||||
    // ============
 | 
			
		||||
    // Capabilities
 | 
			
		||||
    // ============
 | 
			
		||||
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
 | 
			
		||||
    // time. Depending on the number of capabilities, WebdriverIO launches several test
 | 
			
		||||
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
 | 
			
		||||
    // order to group specific specs to a specific capability.
 | 
			
		||||
    //
 | 
			
		||||
    // First, you can define how many instances should be started at the same time. Let's
 | 
			
		||||
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
 | 
			
		||||
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
 | 
			
		||||
    // files and you set maxInstances to 10, all spec files will get tested at the same time
 | 
			
		||||
    // and 30 processes will get spawned. The property handles how many capabilities
 | 
			
		||||
    // from the same test should run tests.
 | 
			
		||||
    //
 | 
			
		||||
    maxInstances: 1,
 | 
			
		||||
    //
 | 
			
		||||
    // If you have trouble getting all important capabilities together, check out the
 | 
			
		||||
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
 | 
			
		||||
    // https://saucelabs.com/platform/platform-configurator
 | 
			
		||||
    //
 | 
			
		||||
    capabilities,
 | 
			
		||||
    //
 | 
			
		||||
    // ===================
 | 
			
		||||
    // Test Configurations
 | 
			
		||||
    // ===================
 | 
			
		||||
    // Define all options that are relevant for the WebdriverIO instance here
 | 
			
		||||
    //
 | 
			
		||||
    // Level of logging verbosity: trace | debug | info | warn | error | silent
 | 
			
		||||
    logLevel: "warn",
 | 
			
		||||
    //
 | 
			
		||||
    // Set specific log levels per logger
 | 
			
		||||
    // loggers:
 | 
			
		||||
    // - webdriver, webdriverio
 | 
			
		||||
    // - @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
 | 
			
		||||
    // - @wdio/mocha-framework, @wdio/jasmine-framework
 | 
			
		||||
    // - @wdio/local-runner
 | 
			
		||||
    // - @wdio/sumologic-reporter
 | 
			
		||||
    // - @wdio/cli, @wdio/config, @wdio/utils
 | 
			
		||||
    // Level of logging verbosity: trace | debug | info | warn | error | silent
 | 
			
		||||
    // logLevels: {
 | 
			
		||||
    //     webdriver: 'info',
 | 
			
		||||
    //     '@wdio/appium-service': 'info'
 | 
			
		||||
    // },
 | 
			
		||||
    //
 | 
			
		||||
    // If you only want to run your tests until a specific amount of tests have failed use
 | 
			
		||||
    // bail (default is 0 - don't bail, run all tests).
 | 
			
		||||
    bail: 0,
 | 
			
		||||
    //
 | 
			
		||||
    // Set a base URL in order to shorten url command calls. If your `url` parameter starts
 | 
			
		||||
    // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
 | 
			
		||||
    // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
 | 
			
		||||
    // gets prepended directly.
 | 
			
		||||
    baseUrl: "http://localhost",
 | 
			
		||||
    //
 | 
			
		||||
    // Default timeout for all waitFor* commands.
 | 
			
		||||
    waitforTimeout: 10000,
 | 
			
		||||
    //
 | 
			
		||||
    // Default timeout in milliseconds for request
 | 
			
		||||
    // if browser driver or grid doesn't send response
 | 
			
		||||
    connectionRetryTimeout: 120000,
 | 
			
		||||
    //
 | 
			
		||||
    // Default request retries count
 | 
			
		||||
    connectionRetryCount: 3,
 | 
			
		||||
    //
 | 
			
		||||
    // Test runner services
 | 
			
		||||
    // Services take over a specific job you don't want to take care of. They enhance
 | 
			
		||||
    // your test setup with almost no effort. Unlike plugins, they don't add new
 | 
			
		||||
    // commands. Instead, they hook themselves up into the test process.
 | 
			
		||||
    // services: [],
 | 
			
		||||
    //
 | 
			
		||||
    // Framework you want to run your specs with.
 | 
			
		||||
    // The following are supported: Mocha, Jasmine, and Cucumber
 | 
			
		||||
    // see also: https://webdriver.io/docs/frameworks
 | 
			
		||||
    //
 | 
			
		||||
    // Make sure you have the wdio adapter package for the specific framework installed
 | 
			
		||||
    // before running any tests.
 | 
			
		||||
    framework: "mocha",
 | 
			
		||||
    //
 | 
			
		||||
    // The number of times to retry the entire specfile when it fails as a whole
 | 
			
		||||
    // specFileRetries: 1,
 | 
			
		||||
    //
 | 
			
		||||
    // Delay in seconds between the spec file retry attempts
 | 
			
		||||
    // specFileRetriesDelay: 0,
 | 
			
		||||
    //
 | 
			
		||||
    // Whether or not retried spec files should be retried immediately or deferred to the end of the queue
 | 
			
		||||
    // specFileRetriesDeferred: false,
 | 
			
		||||
    //
 | 
			
		||||
    // Test reporter for stdout.
 | 
			
		||||
    // The only one supported by default is 'dot'
 | 
			
		||||
    // see also: https://webdriver.io/docs/dot-reporter
 | 
			
		||||
    reporters: ["spec"],
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Options to be passed to Mocha.
 | 
			
		||||
    // See the full list at http://mochajs.org/
 | 
			
		||||
    mochaOpts: {
 | 
			
		||||
        ui: "bdd",
 | 
			
		||||
        timeout: 60000,
 | 
			
		||||
    },
 | 
			
		||||
    //
 | 
			
		||||
    // =====
 | 
			
		||||
    // Hooks
 | 
			
		||||
    // =====
 | 
			
		||||
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
 | 
			
		||||
    // it and to build services around it. You can either apply a single function or an array of
 | 
			
		||||
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
 | 
			
		||||
    // resolved to continue.
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed once before all workers get launched.
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     */
 | 
			
		||||
    // onPrepare: function (config, capabilities) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed before a worker process is spawned and can be used to initialise specific service
 | 
			
		||||
     * for that worker as well as modify runtime environments in an async fashion.
 | 
			
		||||
     * @param  {string} cid      capability id (e.g 0-0)
 | 
			
		||||
     * @param  {object} caps     object containing capabilities for session that will be spawn in the worker
 | 
			
		||||
     * @param  {object} specs    specs to be run in the worker process
 | 
			
		||||
     * @param  {object} args     object that will be merged with the main configuration once worker is initialized
 | 
			
		||||
     * @param  {object} execArgv list of string arguments passed to the worker process
 | 
			
		||||
     */
 | 
			
		||||
    // onWorkerStart: function (cid, caps, specs, args, execArgv) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed just after a worker process has exited.
 | 
			
		||||
     * @param  {string} cid      capability id (e.g 0-0)
 | 
			
		||||
     * @param  {number} exitCode 0 - success, 1 - fail
 | 
			
		||||
     * @param  {object} specs    specs to be run in the worker process
 | 
			
		||||
     * @param  {number} retries  number of retries used
 | 
			
		||||
     */
 | 
			
		||||
    // onWorkerEnd: function (cid, exitCode, specs, retries) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed just before initialising the webdriver session and test framework. It allows you
 | 
			
		||||
     * to manipulate configurations depending on the capability or spec.
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs List of spec file paths that are to be run
 | 
			
		||||
     * @param {string} cid worker id (e.g. 0-0)
 | 
			
		||||
     */
 | 
			
		||||
    // beforeSession: function (config, capabilities, specs, cid) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Runs before a WebdriverIO command gets executed.
 | 
			
		||||
     * @param {string} commandName hook command name
 | 
			
		||||
     * @param {Array} args arguments that command would receive
 | 
			
		||||
     */
 | 
			
		||||
    // beforeCommand: function (commandName, args) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed before the suite starts
 | 
			
		||||
     * @param {object} suite suite details
 | 
			
		||||
     */
 | 
			
		||||
    // beforeSuite: function (suite) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Function to be executed before a test (in Mocha/Jasmine) starts.
 | 
			
		||||
     */
 | 
			
		||||
    // beforeTest: function (test, context) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
 | 
			
		||||
     * beforeEach in Mocha)
 | 
			
		||||
     */
 | 
			
		||||
    // beforeHook: function (test, context) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
 | 
			
		||||
     * afterEach in Mocha)
 | 
			
		||||
     */
 | 
			
		||||
    // afterHook: function (test, context, { error, result, duration, passed, retries }) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Function to be executed after a test (in Mocha/Jasmine only)
 | 
			
		||||
     * @param {object}  test             test object
 | 
			
		||||
     * @param {object}  context          scope object the test was executed with
 | 
			
		||||
     * @param {Error}   result.error     error object in case the test fails, otherwise `undefined`
 | 
			
		||||
     * @param {*}       result.result    return object of test function
 | 
			
		||||
     * @param {number}  result.duration  duration of test
 | 
			
		||||
     * @param {boolean} result.passed    true if test has passed, otherwise false
 | 
			
		||||
     * @param {object}  result.retries   information about spec related retries, e.g. `{ attempts: 0, limit: 0 }`
 | 
			
		||||
     */
 | 
			
		||||
    // Below is the full signature; we're not using any of them.
 | 
			
		||||
    //     afterTest: async function (test, context, { error, result, duration, passed, retries }) {
 | 
			
		||||
    afterTest: async function () {
 | 
			
		||||
        if (lemmeSee) {
 | 
			
		||||
            await browser.pause(500);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed after the suite has ended
 | 
			
		||||
     * @param {object} suite suite details
 | 
			
		||||
     */
 | 
			
		||||
    // afterSuite: function (suite) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Runs after a WebdriverIO command gets executed
 | 
			
		||||
     * @param {string} commandName hook command name
 | 
			
		||||
     * @param {Array} args arguments that command would receive
 | 
			
		||||
     * @param {number} result 0 - command success, 1 - command error
 | 
			
		||||
     * @param {object} error error object if any
 | 
			
		||||
     */
 | 
			
		||||
    // afterCommand: function (commandName, args, result, error) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed after all tests are done. You still have access to all global variables from
 | 
			
		||||
     * the test.
 | 
			
		||||
     * @param {number} result 0 - test pass, 1 - test fail
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs List of spec file paths that ran
 | 
			
		||||
     */
 | 
			
		||||
    // after: function (result, capabilities, specs) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed right after terminating the webdriver session.
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs List of spec file paths that ran
 | 
			
		||||
     */
 | 
			
		||||
    // afterSession: function (config, capabilities, specs) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed after all workers got shut down and the process is about to exit. An error
 | 
			
		||||
     * thrown in the onComplete hook will result in the test run failing.
 | 
			
		||||
     * @param {object} exitCode 0 - success, 1 - fail
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {<Object>} results object containing test results
 | 
			
		||||
     */
 | 
			
		||||
    // onComplete: function(exitCode, config, capabilities, results) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed when a refresh happens.
 | 
			
		||||
     * @param {string} oldSessionId session ID of the old session
 | 
			
		||||
     * @param {string} newSessionId session ID of the new session
 | 
			
		||||
     */
 | 
			
		||||
    // onReload: function(oldSessionId, newSessionId) {
 | 
			
		||||
    // }
 | 
			
		||||
};
 | 
			
		||||
@ -3,34 +3,7 @@
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": ".",
 | 
			
		||||
        "types": ["node", "webdriverio/async", "@wdio/cucumber-framework", "expect-webdriverio"],
 | 
			
		||||
        "target": "esnext",
 | 
			
		||||
        "module": "esnext",
 | 
			
		||||
        "forceConsistentCasingInFileNames": true,
 | 
			
		||||
        "experimentalDecorators": true,
 | 
			
		||||
        "lib": [
 | 
			
		||||
            "ES5",
 | 
			
		||||
            "ES2015",
 | 
			
		||||
            "ES2016",
 | 
			
		||||
            "ES2017",
 | 
			
		||||
            "ES2018",
 | 
			
		||||
            "ES2019",
 | 
			
		||||
            "ES2020",
 | 
			
		||||
            "ESNext",
 | 
			
		||||
            "DOM",
 | 
			
		||||
            "DOM.Iterable",
 | 
			
		||||
            "WebWorker"
 | 
			
		||||
        ],
 | 
			
		||||
        "paths": {
 | 
			
		||||
            "@goauthentik/admin/*": ["./src/admin/*"],
 | 
			
		||||
            "@goauthentik/common/*": ["./src/common/*"],
 | 
			
		||||
            "@goauthentik/components/*": ["./src/components/*"],
 | 
			
		||||
            "@goauthentik/docs/*": ["../website/docs/*"],
 | 
			
		||||
            "@goauthentik/elements/*": ["./src/elements/*"],
 | 
			
		||||
            "@goauthentik/flow/*": ["./src/flow/*"],
 | 
			
		||||
            "@goauthentik/locales/*": ["./src/locales/*"],
 | 
			
		||||
            "@goauthentik/polyfill/*": ["./src/polyfill/*"],
 | 
			
		||||
            "@goauthentik/standalone/*": ["./src/standalone/*"],
 | 
			
		||||
            "@goauthentik/user/*": ["./src/user/*"]
 | 
			
		||||
        }
 | 
			
		||||
        "extends": "./tsconfig.json",
 | 
			
		||||
        "include": ["src", "./tests"]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								web/types/webdriver.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								web/types/webdriver.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
declare namespace WebdriverIO {
 | 
			
		||||
    interface Element {
 | 
			
		||||
        /**
 | 
			
		||||
         * Focus on the element.
 | 
			
		||||
         * @monkeypatch
 | 
			
		||||
         */
 | 
			
		||||
        focus(): Promise<void>;
 | 
			
		||||
        /**
 | 
			
		||||
         * Blur the element.
 | 
			
		||||
         * @monkeypatch
 | 
			
		||||
         */
 | 
			
		||||
        blur(): Promise<void>;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								web/wdio.conf.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								web/wdio.conf.mjs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file WebdriverIO configuration file for **integration tests**.
 | 
			
		||||
 *
 | 
			
		||||
 * @see https://webdriver.io/docs/configurationfile.html
 | 
			
		||||
 */
 | 
			
		||||
import { browser } from "@wdio/globals";
 | 
			
		||||
 | 
			
		||||
import { addCommands } from "./commands.mjs";
 | 
			
		||||
 | 
			
		||||
/// <reference types="@wdio/globals/types" />
 | 
			
		||||
/// <reference types="./types/webdriver.js" />
 | 
			
		||||
 | 
			
		||||
const headless = !!process.env.CI;
 | 
			
		||||
const lemmeSee = !!process.env.WDIO_LEMME_SEE;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @type {WebdriverIO.Capabilities[]}
 | 
			
		||||
 */
 | 
			
		||||
const capabilities = [];
 | 
			
		||||
 | 
			
		||||
if (!process.env.WDIO_SKIP_CHROME) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @satisfies {WebdriverIO.Capabilities}
 | 
			
		||||
     */
 | 
			
		||||
    const chromeBrowserConfig = {
 | 
			
		||||
        "browserName": "chrome",
 | 
			
		||||
        // "wdio:chromedriverOptions": {
 | 
			
		||||
        //     binary: "./node_modules/.bin/chromedriver",
 | 
			
		||||
        // },
 | 
			
		||||
        "goog:chromeOptions": {
 | 
			
		||||
            args: ["disable-infobars", "window-size=1280,800"],
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (headless) {
 | 
			
		||||
        chromeBrowserConfig["goog:chromeOptions"].args.push(
 | 
			
		||||
            "headless",
 | 
			
		||||
            "no-sandbox",
 | 
			
		||||
            "disable-gpu",
 | 
			
		||||
            "disable-setuid-sandbox",
 | 
			
		||||
            "disable-dev-shm-usage",
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    capabilities.push(chromeBrowserConfig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.env.WDIO_TEST_SAFARI) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "safari",
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.env.WDIO_TEST_FIREFOX) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "firefox",
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @satisfies {WebdriverIO.Config}
 | 
			
		||||
 */
 | 
			
		||||
export const config = {
 | 
			
		||||
    runner: "local",
 | 
			
		||||
    tsConfigPath: "./tsconfig.json",
 | 
			
		||||
 | 
			
		||||
    specs: [
 | 
			
		||||
        // "./tests/specs/**/*.ts"
 | 
			
		||||
        "./tests/specs/new-application-by-wizard.ts",
 | 
			
		||||
    ],
 | 
			
		||||
    exclude: [],
 | 
			
		||||
    maxInstances: 1,
 | 
			
		||||
    capabilities,
 | 
			
		||||
 | 
			
		||||
    logLevel: "warn",
 | 
			
		||||
    baseUrl: "http://localhost",
 | 
			
		||||
    waitforTimeout: 10000,
 | 
			
		||||
    connectionRetryTimeout: 120000,
 | 
			
		||||
    connectionRetryCount: 3,
 | 
			
		||||
 | 
			
		||||
    framework: "mocha",
 | 
			
		||||
    reporters: ["spec"],
 | 
			
		||||
    mochaOpts: {
 | 
			
		||||
        ui: "bdd",
 | 
			
		||||
        timeout: 60000,
 | 
			
		||||
    },
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {WebdriverIO.Capabilities} capabilities
 | 
			
		||||
     * @param {string[]} specs
 | 
			
		||||
     * @param {WebdriverIO.Browser} browser
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    before(capabilities, specs, browser) {
 | 
			
		||||
        addCommands(browser);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    afterTest() {
 | 
			
		||||
        if (lemmeSee) return browser.pause(500);
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										391
									
								
								web/wdio.conf.ts
									
									
									
									
									
								
							
							
						
						
									
										391
									
								
								web/wdio.conf.ts
									
									
									
									
									
								
							@ -1,391 +0,0 @@
 | 
			
		||||
/// <reference types="@wdio/browser-runner" />
 | 
			
		||||
import { createBundleDefinitions } from "#bundler/utils/node";
 | 
			
		||||
import { browser } from "@wdio/globals";
 | 
			
		||||
import type { Options } from "@wdio/types";
 | 
			
		||||
import path from "node:path";
 | 
			
		||||
import { fileURLToPath } from "node:url";
 | 
			
		||||
import type { InlineConfig } from "vite";
 | 
			
		||||
import litCSS from "vite-plugin-lit-css";
 | 
			
		||||
import tsconfigPaths from "vite-tsconfig-paths";
 | 
			
		||||
 | 
			
		||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
 | 
			
		||||
 | 
			
		||||
const runHeadless = process.env.CI !== undefined;
 | 
			
		||||
 | 
			
		||||
const testSafari = process.env.WDIO_TEST_SAFARI !== undefined;
 | 
			
		||||
const testFirefox = process.env.WDIO_TEST_FIREFOX !== undefined;
 | 
			
		||||
const skipChrome = process.env.WDIO_SKIP_CHROME !== undefined;
 | 
			
		||||
const lemmeSee = process.env.WDIO_LEMME_SEE !== undefined;
 | 
			
		||||
 | 
			
		||||
const capabilities = [];
 | 
			
		||||
 | 
			
		||||
const DEFAULT_MAX_INSTANCES = 10;
 | 
			
		||||
 | 
			
		||||
if (!skipChrome) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        // capabilities for local browser web tests
 | 
			
		||||
        "browserName": "chrome", // or "firefox", "microsoftedge", "safari"
 | 
			
		||||
        "goog:chromeOptions": {
 | 
			
		||||
            args: [
 | 
			
		||||
                "disable-search-engine-choice-screen",
 | 
			
		||||
                ...(runHeadless
 | 
			
		||||
                    ? [
 | 
			
		||||
                          "headless",
 | 
			
		||||
                          "disable-gpu",
 | 
			
		||||
                          "no-sandbox",
 | 
			
		||||
                          "window-size=1280,672",
 | 
			
		||||
                          "browser-test",
 | 
			
		||||
                      ]
 | 
			
		||||
                    : []),
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (testSafari) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "safari", // or "firefox", "microsoftedge", "safari"
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (testFirefox) {
 | 
			
		||||
    capabilities.push({
 | 
			
		||||
        browserName: "firefox", // or "firefox", "microsoftedge", "safari"
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const maxInstances =
 | 
			
		||||
    process.env.MAX_INSTANCES !== undefined
 | 
			
		||||
        ? parseInt(process.env.MAX_INSTANCES, DEFAULT_MAX_INSTANCES)
 | 
			
		||||
        : runHeadless
 | 
			
		||||
          ? 1
 | 
			
		||||
          : 1;
 | 
			
		||||
 | 
			
		||||
export const config: Options.Testrunner = {
 | 
			
		||||
    //
 | 
			
		||||
    // ====================
 | 
			
		||||
    // Runner Configuration
 | 
			
		||||
    // ====================
 | 
			
		||||
    // WebdriverIO supports running e2e tests as well as unit and component tests.
 | 
			
		||||
    runner: [
 | 
			
		||||
        "browser",
 | 
			
		||||
        {
 | 
			
		||||
            viteConfig: {
 | 
			
		||||
                define: createBundleDefinitions(),
 | 
			
		||||
                plugins: [litCSS(), tsconfigPaths()],
 | 
			
		||||
                resolve: {
 | 
			
		||||
                    alias: {
 | 
			
		||||
                        "@goauthentik/admin": path.resolve(__dirname, "src/admin"),
 | 
			
		||||
                        "@goauthentik/common": path.resolve(__dirname, "src/common"),
 | 
			
		||||
                        "@goauthentik/components": path.resolve(__dirname, "src/components"),
 | 
			
		||||
                        "@goauthentik/docs": path.resolve(__dirname, "../website/docs"),
 | 
			
		||||
                        "@goauthentik/elements": path.resolve(__dirname, "src/elements"),
 | 
			
		||||
                        "@goauthentik/flow": path.resolve(__dirname, "src/flow"),
 | 
			
		||||
                        "@goauthentik/locales": path.resolve(__dirname, "src/locales"),
 | 
			
		||||
                        "@goauthentik/polyfill": path.resolve(__dirname, "src/polyfill"),
 | 
			
		||||
                        "@goauthentik/standalone": path.resolve(__dirname, "src/standalone"),
 | 
			
		||||
                        "@goauthentik/user": path.resolve(__dirname, "src/user"),
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            } satisfies InlineConfig,
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    // @ts-expect-error TS2353: The types are not up-to-date with Wdio9.
 | 
			
		||||
    autoCompileOpts: {
 | 
			
		||||
        autoCompile: true,
 | 
			
		||||
        tsNodeOpts: {
 | 
			
		||||
            project: "./tsconfig.json",
 | 
			
		||||
            transpileOnly: true,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // ==================
 | 
			
		||||
    // Specify Test Files
 | 
			
		||||
    // ==================
 | 
			
		||||
    // Define which test specs should run. The pattern is relative to the directory
 | 
			
		||||
    // of the configuration file being run.
 | 
			
		||||
    //
 | 
			
		||||
    // The specs are defined as an array of spec files (optionally using wildcards
 | 
			
		||||
    // that will be expanded). The test for each spec file will be run in a separate
 | 
			
		||||
    // worker process. In order to have a group of spec files run in the same worker
 | 
			
		||||
    // process simply enclose them in an array within the specs array.
 | 
			
		||||
    //
 | 
			
		||||
    // The path of the spec files will be resolved relative from the directory of
 | 
			
		||||
    // of the config file unless it's absolute.
 | 
			
		||||
    //
 | 
			
		||||
    specs: ["./src/**/*.test.ts"],
 | 
			
		||||
    // Patterns to exclude.
 | 
			
		||||
    exclude: [
 | 
			
		||||
        // 'path/to/excluded/files'
 | 
			
		||||
    ],
 | 
			
		||||
    //
 | 
			
		||||
    // ============
 | 
			
		||||
    // Capabilities
 | 
			
		||||
    // ============
 | 
			
		||||
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
 | 
			
		||||
    // time. Depending on the number of capabilities, WebdriverIO launches several test
 | 
			
		||||
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
 | 
			
		||||
    // order to group specific specs to a specific capability.
 | 
			
		||||
    //
 | 
			
		||||
    // First, you can define how many instances should be started at the same time. Let's
 | 
			
		||||
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
 | 
			
		||||
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
 | 
			
		||||
    // files and you set maxInstances to 10, all spec files will get tested at the same time
 | 
			
		||||
    // and 30 processes will get spawned. The property handles how many capabilities
 | 
			
		||||
    // from the same test should run tests.
 | 
			
		||||
    //
 | 
			
		||||
    maxInstances,
 | 
			
		||||
    //
 | 
			
		||||
    // If you have trouble getting all important capabilities together, check out the
 | 
			
		||||
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
 | 
			
		||||
    // https://saucelabs.com/platform/platform-configurator
 | 
			
		||||
    //
 | 
			
		||||
    capabilities,
 | 
			
		||||
    //
 | 
			
		||||
    // ===================
 | 
			
		||||
    // Test Configurations
 | 
			
		||||
    // ===================
 | 
			
		||||
    // Define all options that are relevant for the WebdriverIO instance here
 | 
			
		||||
    //
 | 
			
		||||
    // Level of logging verbosity: trace | debug | info | warn | error | silent
 | 
			
		||||
    logLevel: "warn",
 | 
			
		||||
    //
 | 
			
		||||
    // Set specific log levels per logger
 | 
			
		||||
    // loggers:
 | 
			
		||||
    // - webdriver, webdriverio
 | 
			
		||||
    // - @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
 | 
			
		||||
    // - @wdio/mocha-framework, @wdio/jasmine-framework
 | 
			
		||||
    // - @wdio/local-runner
 | 
			
		||||
    // - @wdio/sumologic-reporter
 | 
			
		||||
    // - @wdio/cli, @wdio/config, @wdio/utils
 | 
			
		||||
    // Level of logging verbosity: trace | debug | info | warn | error | silent
 | 
			
		||||
    // logLevels: {
 | 
			
		||||
    //     webdriver: 'info',
 | 
			
		||||
    //     '@wdio/appium-service': 'info'
 | 
			
		||||
    // },
 | 
			
		||||
    //
 | 
			
		||||
    // If you only want to run your tests until a specific amount of tests have failed use
 | 
			
		||||
    // bail (default is 0 - don't bail, run all tests).
 | 
			
		||||
    bail: 0,
 | 
			
		||||
    //
 | 
			
		||||
    // Set a base URL in order to shorten url command calls. If your `url` parameter starts
 | 
			
		||||
    // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
 | 
			
		||||
    // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
 | 
			
		||||
    // gets prepended directly.
 | 
			
		||||
    // baseUrl: 'http://localhost:8080',
 | 
			
		||||
    //
 | 
			
		||||
    // Default timeout for all waitFor* commands.
 | 
			
		||||
    waitforTimeout: 12000,
 | 
			
		||||
    //
 | 
			
		||||
    // Default timeout in milliseconds for request
 | 
			
		||||
    // if browser driver or grid doesn't send response
 | 
			
		||||
    connectionRetryTimeout: 12000,
 | 
			
		||||
    //
 | 
			
		||||
    // Default request retries count
 | 
			
		||||
    connectionRetryCount: 3,
 | 
			
		||||
    //
 | 
			
		||||
    // Test runner services
 | 
			
		||||
    // Services take over a specific job you don't want to take care of. They enhance
 | 
			
		||||
    // your test setup with almost no effort. Unlike plugins, they don't add new
 | 
			
		||||
    // commands. Instead, they hook themselves up into the test process.
 | 
			
		||||
    // services: [],
 | 
			
		||||
    //
 | 
			
		||||
    // Framework you want to run your specs with.
 | 
			
		||||
    // The following are supported: Mocha, Jasmine, and Cucumber
 | 
			
		||||
    // see also: https://webdriver.io/docs/frameworks
 | 
			
		||||
    //
 | 
			
		||||
    // Make sure you have the wdio adapter package for the specific framework installed
 | 
			
		||||
    // before running any tests.
 | 
			
		||||
    framework: "mocha",
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // The number of times to retry the entire specfile when it fails as a whole
 | 
			
		||||
    // specFileRetries: 1,
 | 
			
		||||
    //
 | 
			
		||||
    // Delay in seconds between the spec file retry attempts
 | 
			
		||||
    // specFileRetriesDelay: 0,
 | 
			
		||||
    //
 | 
			
		||||
    // Whether or not retried spec files should be retried immediately or deferred to the end of the queue
 | 
			
		||||
    // specFileRetriesDeferred: false,
 | 
			
		||||
    //
 | 
			
		||||
    // Test reporter for stdout.
 | 
			
		||||
    // The only one supported by default is 'dot'
 | 
			
		||||
    // see also: https://webdriver.io/docs/dot-reporter
 | 
			
		||||
    reporters: ["spec"],
 | 
			
		||||
 | 
			
		||||
    // Options to be passed to Mocha.
 | 
			
		||||
    // See the full list at http://mochajs.org/
 | 
			
		||||
    mochaOpts: {
 | 
			
		||||
        ui: "bdd",
 | 
			
		||||
        timeout: 60000,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // =====
 | 
			
		||||
    // Hooks
 | 
			
		||||
    // =====
 | 
			
		||||
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
 | 
			
		||||
    // it and to build services around it. You can either apply a single function or an array of
 | 
			
		||||
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
 | 
			
		||||
    // resolved to continue.
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed once before all workers get launched.
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     */
 | 
			
		||||
    // onPrepare: function (config, capabilities) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed before a worker process is spawned and can be used to initialize specific service
 | 
			
		||||
     * for that worker as well as modify runtime environments in an async fashion.
 | 
			
		||||
     * @param  {string} cid      capability id (e.g 0-0)
 | 
			
		||||
     * @param  {object} caps     object containing capabilities for session that will be spawn in the worker
 | 
			
		||||
     * @param  {object} specs    specs to be run in the worker process
 | 
			
		||||
     * @param  {object} args     object that will be merged with the main configuration once worker is initialized
 | 
			
		||||
     * @param  {object} execArgv list of string arguments passed to the worker process
 | 
			
		||||
     */
 | 
			
		||||
    // onWorkerStart: function (cid, caps, specs, args, execArgv) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed just after a worker process has exited.
 | 
			
		||||
     * @param  {string} cid      capability id (e.g 0-0)
 | 
			
		||||
     * @param  {number} exitCode 0 - success, 1 - fail
 | 
			
		||||
     * @param  {object} specs    specs to be run in the worker process
 | 
			
		||||
     * @param  {number} retries  number of retries used
 | 
			
		||||
     */
 | 
			
		||||
    // onWorkerEnd: function (cid, exitCode, specs, retries) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed just before initialising the webdriver session and test framework. It allows you
 | 
			
		||||
     * to manipulate configurations depending on the capability or spec.
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs List of spec file paths that are to be run
 | 
			
		||||
     * @param {string} cid worker id (e.g. 0-0)
 | 
			
		||||
     */
 | 
			
		||||
    // beforeSession: function (config, capabilities, specs, cid) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed before test execution begins. At this point you can access to all global
 | 
			
		||||
     * variables like `browser`. It is the perfect place to define custom commands.
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs        List of spec file paths that are to be run
 | 
			
		||||
     * @param {object}         browser      instance of created browser/device session
 | 
			
		||||
     */
 | 
			
		||||
    // before: function (capabilities, specs) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Runs before a WebdriverIO command gets executed.
 | 
			
		||||
     * @param {string} commandName hook command name
 | 
			
		||||
     * @param {Array} args arguments that command would receive
 | 
			
		||||
     */
 | 
			
		||||
    // beforeCommand: function (commandName, args) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed before the suite starts
 | 
			
		||||
     * @param {object} suite suite details
 | 
			
		||||
     */
 | 
			
		||||
    // beforeSuite: function (suite) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Function to be executed before a test (in Mocha/Jasmine) starts.
 | 
			
		||||
     */
 | 
			
		||||
    // beforeTest: function (test, context) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
 | 
			
		||||
     * beforeEach in Mocha)
 | 
			
		||||
     */
 | 
			
		||||
    // beforeHook: function (test, context, hookName) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
 | 
			
		||||
     * afterEach in Mocha)
 | 
			
		||||
     */
 | 
			
		||||
    // afterHook: function (test, context, { error, result, duration, passed, retries }, hookName) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Function to be executed after a test (in Mocha/Jasmine only)
 | 
			
		||||
     * @param {object}  test             test object
 | 
			
		||||
     * @param {object}  context          scope object the test was executed with
 | 
			
		||||
     * @param {Error}   result.error     error object in case the test fails, otherwise `undefined`
 | 
			
		||||
     * @param {*}       result.result    return object of test function
 | 
			
		||||
     * @param {number}  result.duration  duration of test
 | 
			
		||||
     * @param {boolean} result.passed    true if test has passed, otherwise false
 | 
			
		||||
     * @param {object}  result.retries   information about spec related retries, e.g. `{ attempts: 0, limit: 0 }`
 | 
			
		||||
     */
 | 
			
		||||
    afterTest: async function (
 | 
			
		||||
        _test,
 | 
			
		||||
        _context,
 | 
			
		||||
        { error: _error, result: _result, duration: _duration, passed: _passed, retries: _retries },
 | 
			
		||||
    ) {
 | 
			
		||||
        if (lemmeSee) {
 | 
			
		||||
            // @ts-expect-error TODO
 | 
			
		||||
            await browser.pause(500);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed after the suite has ended
 | 
			
		||||
     * @param {object} suite suite details
 | 
			
		||||
     */
 | 
			
		||||
    // afterSuite: function (suite) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Runs after a WebdriverIO command gets executed
 | 
			
		||||
     * @param {string} commandName hook command name
 | 
			
		||||
     * @param {Array} args arguments that command would receive
 | 
			
		||||
     * @param {number} result 0 - command success, 1 - command error
 | 
			
		||||
     * @param {object} error error object if any
 | 
			
		||||
     */
 | 
			
		||||
    // afterCommand: function (commandName, args, result, error) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed after all tests are done. You still have access to all global variables from
 | 
			
		||||
     * the test.
 | 
			
		||||
     * @param {number} result 0 - test pass, 1 - test fail
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs List of spec file paths that ran
 | 
			
		||||
     */
 | 
			
		||||
    // after: function (result, capabilities, specs) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed right after terminating the webdriver session.
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {Array.<String>} specs List of spec file paths that ran
 | 
			
		||||
     */
 | 
			
		||||
    // afterSession: function (config, capabilities, specs) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed after all workers got shut down and the process is about to exit. An error
 | 
			
		||||
     * thrown in the onComplete hook will result in the test run failing.
 | 
			
		||||
     * @param {object} exitCode 0 - success, 1 - fail
 | 
			
		||||
     * @param {object} config wdio configuration object
 | 
			
		||||
     * @param {Array.<Object>} capabilities list of capabilities details
 | 
			
		||||
     * @param {<Object>} results object containing test results
 | 
			
		||||
     */
 | 
			
		||||
    // onComplete: function(exitCode, config, capabilities, results) {
 | 
			
		||||
    // },
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets executed when a refresh happens.
 | 
			
		||||
     * @param {string} oldSessionId session ID of the old session
 | 
			
		||||
     * @param {string} newSessionId session ID of the new session
 | 
			
		||||
     */
 | 
			
		||||
    // onReload: function(oldSessionId, newSessionId) {
 | 
			
		||||
    // }
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed before a WebdriverIO assertion happens.
 | 
			
		||||
     * @param {object} params information about the assertion to be executed
 | 
			
		||||
     */
 | 
			
		||||
    // beforeAssertion: function(params) {
 | 
			
		||||
    // }
 | 
			
		||||
    /**
 | 
			
		||||
     * Hook that gets executed after a WebdriverIO assertion happened.
 | 
			
		||||
     * @param {object} params information about the assertion that was executed, including its results
 | 
			
		||||
     */
 | 
			
		||||
    // afterAssertion: function(params) {
 | 
			
		||||
    // }
 | 
			
		||||
};
 | 
			
		||||
@ -1,6 +1,16 @@
 | 
			
		||||
export default {
 | 
			
		||||
/**
 | 
			
		||||
 * @file Web Test Runner configuration.
 | 
			
		||||
 * @see https://modern-web.dev/docs/test-runner/cli-and-configuration/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @type {import('@web/test-runner').TestRunnerConfig}
 | 
			
		||||
 */
 | 
			
		||||
const config = {
 | 
			
		||||
    files: ["dist/**/*.spec.js"],
 | 
			
		||||
    nodeResolve: {
 | 
			
		||||
        exportConditions: ["browser", "production"],
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default config;
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,6 @@ Depending on platform, some native dependencies might be required. On macOS, run
 | 
			
		||||
4. From the cloned repository root, install the front-end dependencies using NPM.
 | 
			
		||||
 | 
			
		||||
    ```shell
 | 
			
		||||
    cd web
 | 
			
		||||
    npm ci
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,12 @@
 | 
			
		||||
 * @import * as OpenApiPlugin from "docusaurus-plugin-openapi-docs";
 | 
			
		||||
 * @import { BuildUrlValues } from "remark-github";
 | 
			
		||||
 */
 | 
			
		||||
import { MonoRepoRoot } from "@goauthentik/core/paths/node";
 | 
			
		||||
import { createDocusaurusConfig } from "@goauthentik/docusaurus-config";
 | 
			
		||||
import { cp } from "node:fs/promises";
 | 
			
		||||
import { createRequire } from "node:module";
 | 
			
		||||
import { resolve } from "node:path";
 | 
			
		||||
import { fileURLToPath } from "node:url";
 | 
			
		||||
import remarkDirective from "remark-directive";
 | 
			
		||||
import remarkGithub, { defaultBuildUrl } from "remark-github";
 | 
			
		||||
 | 
			
		||||
@ -16,7 +20,30 @@ import remarkSupportDirective from "./remark/support-directive.mjs";
 | 
			
		||||
import remarkVersionDirective from "./remark/version-directive.mjs";
 | 
			
		||||
 | 
			
		||||
const require = createRequire(import.meta.url);
 | 
			
		||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
 | 
			
		||||
const staticDirectory = resolve(__dirname, "static");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {string} fileName
 | 
			
		||||
 */
 | 
			
		||||
function copyStaticFile(fileName) {
 | 
			
		||||
    const source = resolve(MonoRepoRoot, fileName);
 | 
			
		||||
    const destination = resolve(staticDirectory, fileName);
 | 
			
		||||
 | 
			
		||||
    return cp(source, destination).catch((error) => {
 | 
			
		||||
        const wrapper = new Error(`Failed to copy file "${source}" to "${destination}"`);
 | 
			
		||||
 | 
			
		||||
        wrapper.cause = error;
 | 
			
		||||
 | 
			
		||||
        throw wrapper;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
await Promise.all([
 | 
			
		||||
    // ---
 | 
			
		||||
    copyStaticFile("docker-compose.yml"),
 | 
			
		||||
    copyStaticFile("schema.yml"),
 | 
			
		||||
]);
 | 
			
		||||
/**
 | 
			
		||||
 * Documentation site configuration for Docusaurus.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28003
									
								
								website/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										28003
									
								
								website/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -4,24 +4,20 @@
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "run-s build:docker build:schema build:api build:docusaurus",
 | 
			
		||||
        "build-bundled": "run-s build:schema build:api build:docusaurus",
 | 
			
		||||
        "build": "run-s build:api build:docusaurus",
 | 
			
		||||
        "build:api": "docusaurus gen-api-docs all",
 | 
			
		||||
        "build:docker": "cp ../docker-compose.yml ./static/docker-compose.yml",
 | 
			
		||||
        "build:docusaurus": "cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build",
 | 
			
		||||
        "build:schema": "cp -f ../schema.yml ./static/schema.yml",
 | 
			
		||||
        "deploy": "docusaurus deploy",
 | 
			
		||||
        "docusaurus": "docusaurus",
 | 
			
		||||
        "lint": "eslint --fix .",
 | 
			
		||||
        "lint-check": "eslint --max-warnings 0 .",
 | 
			
		||||
        "lint:lockfile": "echo 'Skipping lockfile linting'",
 | 
			
		||||
        "prettier": "prettier --write .",
 | 
			
		||||
        "prettier-check": "prettier --check .",
 | 
			
		||||
        "serve": "docusaurus serve",
 | 
			
		||||
        "start": "docusaurus start",
 | 
			
		||||
        "swizzle": "docusaurus swizzle",
 | 
			
		||||
        "test": "node --test",
 | 
			
		||||
        "watch": "run-s build:schema build:api start"
 | 
			
		||||
        "watch": "run-s build:api start"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@docusaurus/core": "^3.7.0",
 | 
			
		||||
@ -44,15 +40,17 @@
 | 
			
		||||
        "react-dom": "^18.3.1",
 | 
			
		||||
        "remark-directive": "^4.0.0",
 | 
			
		||||
        "remark-github": "^12.0.0",
 | 
			
		||||
        "semver": "^7.7.2"
 | 
			
		||||
        "semver": "^7.7.2",
 | 
			
		||||
        "vscode-languageserver-types": "3.17.5"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@docusaurus/module-type-aliases": "^3.7.0",
 | 
			
		||||
        "@docusaurus/tsconfig": "^3.7.0",
 | 
			
		||||
        "@docusaurus/types": "^3.7.0",
 | 
			
		||||
        "@eslint/js": "^9.27.0",
 | 
			
		||||
        "@goauthentik/eslint-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/core": "^1.0.0",
 | 
			
		||||
        "@goauthentik/eslint-config": "^1.0.5",
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.5",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
        "@types/lodash": "^4.17.17",
 | 
			
		||||
@ -86,7 +84,7 @@
 | 
			
		||||
        "lightningcss-linux-x64-gnu": "1.30.1"
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=22.14.0"
 | 
			
		||||
        "node": ">=22.15.1"
 | 
			
		||||
    },
 | 
			
		||||
    "browserslist": {
 | 
			
		||||
        "production": [
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user