mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 10:47:37 +00:00
Merge branch 'main' into copilot/fix-10389
This commit is contained in:
@@ -8,9 +8,13 @@ ENV SHELL=/bin/bash \
|
||||
PNPM_HOME=/home/node/.local/share/pnpm \
|
||||
PATH=/home/node/.local/share/pnpm:$PATH
|
||||
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get --no-install-recommends install -y \
|
||||
# Cypress dependencies
|
||||
libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb && \
|
||||
apt-get clean && \
|
||||
corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@9.1.2 --activate
|
||||
corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@10.13.1 --activate
|
||||
|
||||
COPY --chown=node:node commands /commands
|
||||
|
||||
USER node
|
||||
|
2
.devcontainer/base/Dockerfile.dockerignore
Normal file
2
.devcontainer/base/Dockerfile.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!commands
|
39
.devcontainer/base/commands/login-integration.post-attach.sh
Executable file
39
.devcontainer/base/commands/login-integration.post-attach.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
|
||||
set -e
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo -e "THANKS FOR CONTRIBUTING TO ZITADEL 🚀"
|
||||
echo
|
||||
echo "Your dev container is configured for fixing login integration tests."
|
||||
echo "The login is running in a separate container with the same configuration."
|
||||
echo "It calls the mock-zitadel container which provides a mocked Zitadel gRPC API."
|
||||
echo
|
||||
echo "Also the test suite is configured correctly."
|
||||
echo "For example, run a single test file:"
|
||||
echo "pnpm cypress run --spec integration/integration/login.cy.ts"
|
||||
echo
|
||||
echo "You can also run the test interactively."
|
||||
echo "However, this is only possible from outside the dev container."
|
||||
echo "On your host machine, run:"
|
||||
echo "cd apps/login"
|
||||
echo "pnpm cypress open"
|
||||
echo
|
||||
echo "If you want to change the login code, you can replace the login container by a hot reloading dev server."
|
||||
echo "docker stop login-integration"
|
||||
echo "pnpm turbo dev"
|
||||
echo "Navigate to the page you want to fix, for example:"
|
||||
echo "http://localhost:3001/ui/v2/login/verify?userId=221394658884845598&code=abc"
|
||||
echo "Change some code and reload the page for instant feedback."
|
||||
echo
|
||||
echo "When you are done, make sure all integration tests pass:"
|
||||
echo "pnpm cypress run"
|
||||
echo
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
|
||||
exit 0
|
||||
fi
|
18
.devcontainer/base/commands/login-integration.update-content.sh
Executable file
18
.devcontainer/base/commands/login-integration.update-content.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
|
||||
echo "Running in fail-on-errors mode"
|
||||
set -e
|
||||
fi
|
||||
|
||||
pnpm install --frozen-lockfile \
|
||||
--filter @zitadel/login \
|
||||
--filter @zitadel/client \
|
||||
--filter @zitadel/proto \
|
||||
--filter zitadel-monorepo
|
||||
pnpm cypress install
|
||||
pnpm test:integration:login
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
|
||||
exit 0
|
||||
fi
|
30
.devcontainer/base/commands/turbo-lint-unit.post-attach.sh
Executable file
30
.devcontainer/base/commands/turbo-lint-unit.post-attach.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
|
||||
set -e
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo -e "THANKS FOR CONTRIBUTING TO ZITADEL 🚀"
|
||||
echo
|
||||
echo "Your dev container is configured for fixing linting and unit tests."
|
||||
echo "No other services are running alongside this container."
|
||||
echo
|
||||
echo "To fix all auto-fixable linting errors, run:"
|
||||
echo "pnpm turbo lint:fix"
|
||||
echo
|
||||
echo "To watch console linting errors, run:"
|
||||
echo "pnpm turbo watch lint --filter console"
|
||||
echo
|
||||
echo "To watch @zitadel/client unit test failures, run:"
|
||||
echo "pnpm turbo watch test:unit --filter @zitadel/client"
|
||||
echo
|
||||
echo "To watch @zitadel/login relevant unit tests and linting failures, run:"
|
||||
echo "pnpm turbo watch lint test:unit --filter @zitadel/login..."
|
||||
echo
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
|
||||
exit 0
|
||||
fi
|
12
.devcontainer/base/commands/turbo-lint-unit.update-content.sh
Executable file
12
.devcontainer/base/commands/turbo-lint-unit.update-content.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
|
||||
set -e
|
||||
fi
|
||||
|
||||
pnpm install --frozen-lockfile --recursive
|
||||
pnpm turbo lint test:unit
|
||||
|
||||
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
|
||||
exit 0
|
||||
fi
|
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
|
||||
"name": "devcontainer",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"name": "Base: Build and Run the Components you need",
|
||||
"dockerComposeFile": "docker-compose.yaml",
|
||||
"service": "devcontainer",
|
||||
"runServices": [
|
||||
"devContainer",
|
||||
"db"
|
||||
],
|
||||
"workspaceFolder": "/workspaces",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/go:1": {
|
||||
"version": "1.24"
|
||||
},
|
||||
"ghcr.io/guiyomh/features/golangci-lint:0": {},
|
||||
"ghcr.io/jungaretti/features/make:1": {}
|
||||
"remoteEnv": {
|
||||
"DISPLAY": ""
|
||||
},
|
||||
"forwardPorts": [
|
||||
3000,
|
||||
@@ -17,12 +17,13 @@
|
||||
4200,
|
||||
8080
|
||||
],
|
||||
"onCreateCommand": "pnpm install -g sass@1.64.1",
|
||||
"customizations": {
|
||||
"jetbrains": {
|
||||
"settings": {
|
||||
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
|
||||
}
|
||||
}
|
||||
"onCreateCommand": "pnpm install --frozen-lockfile --recursive --prefer-offline",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/go:1": {
|
||||
"version": "1.24"
|
||||
},
|
||||
"ghcr.io/guiyomh/features/golangci-lint:0": {},
|
||||
"ghcr.io/jungaretti/features/make:1": {},
|
||||
"ghcr.io/devcontainers/features/docker-outside-of-docker": {}
|
||||
}
|
||||
}
|
@@ -1,20 +1,11 @@
|
||||
x-build-cache: &build-cache
|
||||
cache_from:
|
||||
- type=gha
|
||||
cache_to:
|
||||
- type=gha,mode=max
|
||||
|
||||
services:
|
||||
|
||||
devcontainer:
|
||||
container_name: devcontainer
|
||||
build:
|
||||
context: .
|
||||
<<: *build-cache
|
||||
context: ../base
|
||||
volumes:
|
||||
- ../../:/workspaces:cached
|
||||
- /tmp/.X11-unix:/tmp/.X11-unix:cached
|
||||
- home-dir:/home/node:delegated
|
||||
command: sleep infinity
|
||||
working_dir: /workspaces
|
||||
environment:
|
||||
@@ -39,34 +30,9 @@ services:
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
||||
mock-zitadel:
|
||||
container_name: mock-zitadel
|
||||
build:
|
||||
context: ../../apps/login/integration/core-mock
|
||||
<<: *build-cache
|
||||
ports:
|
||||
- 22220:22220
|
||||
- 22222:22222
|
||||
|
||||
login-integration:
|
||||
container_name: login-integration
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: build/login/Dockerfile
|
||||
<<: *build-cache
|
||||
image: "${LOGIN_TAG:-zitadel-login:local}"
|
||||
env_file: ../../apps/login/.env.test
|
||||
network_mode: service:devcontainer
|
||||
environment:
|
||||
NODE_ENV: test
|
||||
PORT: 3001
|
||||
depends_on:
|
||||
mock-zitadel:
|
||||
condition: service_started
|
||||
|
||||
zitadel:
|
||||
image: "${ZITADEL_TAG:-ghcr.io/zitadel/zitadel:v4.0.0-rc.2}"
|
||||
container_name: zitadel
|
||||
image: "${ZITADEL_TAG:-ghcr.io/zitadel/zitadel:latest}"
|
||||
command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml'
|
||||
volumes:
|
||||
- ../../apps/login/acceptance/pat:/pat:delegated
|
||||
@@ -89,7 +55,6 @@ services:
|
||||
build:
|
||||
context: ../../apps/login/acceptance/setup
|
||||
dockerfile: ../go-command.Dockerfile
|
||||
<<: *build-cache
|
||||
entrypoint: "./setup.sh"
|
||||
network_mode: service:devcontainer
|
||||
environment:
|
||||
@@ -111,7 +76,7 @@ services:
|
||||
|
||||
login-acceptance:
|
||||
container_name: login
|
||||
image: "${LOGIN_TAG:-ghcr.io/zitadel/zitadel-login:v4.0.0-rc.2}"
|
||||
image: "${LOGIN_TAG:-ghcr.io/zitadel/zitadel-login:latest}"
|
||||
network_mode: service:devcontainer
|
||||
volumes:
|
||||
- ../../apps/login/.env.test.local:/env-files/.env:cached
|
||||
@@ -126,7 +91,6 @@ services:
|
||||
dockerfile: ../go-command.Dockerfile
|
||||
args:
|
||||
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
|
||||
<<: *build-cache
|
||||
environment:
|
||||
PORT: '3333'
|
||||
command:
|
||||
@@ -151,7 +115,6 @@ services:
|
||||
dockerfile: ../go-command.Dockerfile
|
||||
args:
|
||||
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
|
||||
<<: *build-cache
|
||||
network_mode: service:devcontainer
|
||||
environment:
|
||||
API_URL: 'http://localhost:8080'
|
||||
@@ -175,7 +138,6 @@ services:
|
||||
# dockerfile: ../../go-command.Dockerfile
|
||||
# args:
|
||||
# - LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
|
||||
# <<: *build-cache
|
||||
# network_mode: service:devcontainer
|
||||
# environment:
|
||||
# API_URL: 'http://localhost:8080'
|
||||
@@ -197,7 +159,6 @@ services:
|
||||
dockerfile: ../go-command.Dockerfile
|
||||
args:
|
||||
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
|
||||
<<: *build-cache
|
||||
network_mode: service:devcontainer
|
||||
environment:
|
||||
API_URL: 'http://localhost:8080'
|
||||
@@ -219,7 +180,6 @@ services:
|
||||
# dockerfile: ../../go-command.Dockerfile
|
||||
# args:
|
||||
# - LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
|
||||
# <<: *build-cache
|
||||
# network_mode: service:devcontainer
|
||||
# environment:
|
||||
# API_URL: 'http://localhost:8080'
|
||||
@@ -236,4 +196,3 @@ services:
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
home-dir:
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
|
||||
"name": "login-integration-debug",
|
||||
"dockerComposeFile": [
|
||||
"../base/docker-compose.yml",
|
||||
"docker-compose.yml"
|
||||
],
|
||||
"service": "login-integration-debug",
|
||||
"runServices": ["login-integration-debug"],
|
||||
"workspaceFolder": "/workspaces",
|
||||
"forwardPorts": [3001],
|
||||
"onCreateCommand": "pnpm install --recursive",
|
||||
"postAttachCommand": "pnpm turbo daemon clean; pnpm turbo @zitadel/login#dev test:integration:login:debug",
|
||||
"customizations": {
|
||||
"jetbrains": {
|
||||
"settings": {
|
||||
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
services:
|
||||
login-integration-debug:
|
||||
extends:
|
||||
file: ../base/docker-compose.yml
|
||||
service: devcontainer
|
||||
container_name: login-integration-debug
|
||||
depends_on:
|
||||
mock-zitadel:
|
||||
condition: service_started
|
@@ -1,19 +1,26 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
|
||||
"name": "login-integration",
|
||||
"name": "Login Integration",
|
||||
"dockerComposeFile": [
|
||||
"../base/docker-compose.yml"
|
||||
"./docker-compose.yaml"
|
||||
],
|
||||
"service": "devcontainer",
|
||||
"runServices": ["login-integration"],
|
||||
"workspaceFolder": "/workspaces",
|
||||
"forwardPorts": [3001],
|
||||
"onCreateCommand": "pnpm install --frozen-lockfile --recursive && cd apps/login/packages/integration && pnpm cypress install && pnpm test:integration:login",
|
||||
"customizations": {
|
||||
"jetbrains": {
|
||||
"settings": {
|
||||
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
|
||||
}
|
||||
}
|
||||
"service": "login-integration-dev",
|
||||
"runServices": [
|
||||
"login-integration"
|
||||
],
|
||||
"workspaceFolder": "/workspaces/apps/login",
|
||||
"forwardPorts": [
|
||||
22220,
|
||||
22222,
|
||||
3001
|
||||
],
|
||||
"remoteEnv": {
|
||||
"FAIL_COMMANDS_ON_ERRORS": "${localEnv:FAIL_COMMANDS_ON_ERRORS}",
|
||||
"DISPLAY": ""
|
||||
},
|
||||
"updateContentCommand": "/commands/login-integration.update-content.sh",
|
||||
"postAttachCommand": "/commands/login-integration.post-attach.sh",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-outside-of-docker": {}
|
||||
}
|
||||
}
|
||||
|
35
.devcontainer/login-integration/docker-compose.yaml
Normal file
35
.devcontainer/login-integration/docker-compose.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
services:
|
||||
login-integration-dev:
|
||||
extends:
|
||||
file: ../base/docker-compose.yaml
|
||||
service: devcontainer
|
||||
container_name: login-integration-dev
|
||||
env_file: ../../apps/login/.env.test
|
||||
environment:
|
||||
CORE_MOCK_STUBS_URL: http://localhost:22220/v1/stubs
|
||||
LOGIN_BASE_URL: http://localhost:3001/ui/v2/login
|
||||
CYPRESS_CACHE_FOLDER: /workspaces/.artifacts/cypress
|
||||
network_mode: service:mock-zitadel
|
||||
depends_on:
|
||||
login-integration:
|
||||
condition: service_healthy
|
||||
|
||||
login-integration:
|
||||
container_name: login-integration
|
||||
image: "${LOGIN_TAG:-ghcr.io/zitadel/zitadel-login:latest}"
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: build/login/Dockerfile
|
||||
env_file: ../../apps/login/.env.test
|
||||
network_mode: service:mock-zitadel
|
||||
|
||||
mock-zitadel:
|
||||
container_name: mock-zitadel
|
||||
build:
|
||||
context: ../../apps/login/integration/core-mock
|
||||
additional_contexts:
|
||||
- zitadel-protos=../../proto
|
||||
ports:
|
||||
- 22220:22220
|
||||
- 22222:22222
|
||||
- 3001:3001
|
22
.devcontainer/login-subtree/devcontainer.json
Normal file
22
.devcontainer/login-subtree/devcontainer.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.base.schema.json",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:20-bookworm",
|
||||
"name": "Login Subtree Container - Use the Login As If You Would Have Forked the Mirror Repo",
|
||||
"workspaceFolder": "/login",
|
||||
"workspaceMount": "source=${localWorkspaceFolder}/apps/login,target=/login,type=bind,consistency=cached",
|
||||
"mounts": [],
|
||||
"forwardPorts": [
|
||||
22220,
|
||||
22222,
|
||||
3000,
|
||||
3001
|
||||
],
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/go:1": {
|
||||
"version": "1.24"
|
||||
},
|
||||
"ghcr.io/guiyomh/features/golangci-lint:0": {},
|
||||
"ghcr.io/jungaretti/features/make:1": {},
|
||||
"ghcr.io/devcontainers/features/docker-outside-of-docker": {}
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
|
||||
"name": "turbo-lint-unit-debug",
|
||||
"dockerComposeFile": [
|
||||
"../base/docker-compose.yml",
|
||||
"docker-compose.yml"
|
||||
],
|
||||
"service": "turbo-lint-unit-debug",
|
||||
"runServices": ["turbo-lint-unit-debug"],
|
||||
"workspaceFolder": "/workspaces",
|
||||
"forwardPorts": [3001],
|
||||
"onCreateCommand": "pnpm install --recursive",
|
||||
"postAttachCommand": "pnpm turbo daemon clean; pnpm turbo watch lint test:unit",
|
||||
"customizations": {
|
||||
"jetbrains": {
|
||||
"settings": {
|
||||
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
services:
|
||||
turbo-lint-unit-debug:
|
||||
extends:
|
||||
file: ../base/docker-compose.yml
|
||||
service: devcontainer
|
||||
container_name: turbo-lint-unit-debug
|
@@ -1,18 +1,20 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
|
||||
"name": "turbo-lint-unit",
|
||||
"name": "Turbo Lint and Unit Tests",
|
||||
"dockerComposeFile": [
|
||||
"../base/docker-compose.yml"
|
||||
"../base/docker-compose.yaml"
|
||||
],
|
||||
"service": "devcontainer",
|
||||
"runServices": ["devcontainer"],
|
||||
"runServices": [
|
||||
"devcontainer"
|
||||
],
|
||||
"workspaceFolder": "/workspaces",
|
||||
"postStartCommand": "pnpm install --frozen-lockfile --recursive && pnpm turbo lint test:unit",
|
||||
"customizations": {
|
||||
"jetbrains": {
|
||||
"settings": {
|
||||
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
|
||||
}
|
||||
}
|
||||
}
|
||||
"forwardPorts": [
|
||||
3001
|
||||
],
|
||||
"remoteEnv": {
|
||||
"FAIL_COMMANDS_ON_ERRORS": "${localEnv:FAIL_COMMANDS_ON_ERRORS}"
|
||||
},
|
||||
"updateContentCommand": "/commands/turbo-lint-unit.update-content.sh",
|
||||
"postAttachCommand": "/commands/turbo-lint-unit.post-attach.sh"
|
||||
}
|
@@ -1,11 +1,14 @@
|
||||
|
||||
# .git
|
||||
.codecov
|
||||
.github
|
||||
.gitignore
|
||||
.dockerignore
|
||||
**/Dockerfile
|
||||
/k8s/
|
||||
/node_modules/
|
||||
**/node_modules
|
||||
**/.pnpm-store
|
||||
**/.turbo
|
||||
**/.next
|
||||
/console/src/app/proto/generated/
|
||||
/console/.angular
|
||||
/console/tmp/
|
||||
@@ -24,5 +27,5 @@ console/.angular
|
||||
console/node_modules
|
||||
console/src/app/proto/generated/
|
||||
console/tmp/
|
||||
.vscode
|
||||
build/*.Dockerfile
|
||||
|
||||
|
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@@ -102,6 +102,12 @@ jobs:
|
||||
login_build_image_name: "ghcr.io/zitadel/zitadel-login-build"
|
||||
node_version: "20"
|
||||
|
||||
login-integration-test:
|
||||
uses: ./.github/workflows/login-integration-test.yml
|
||||
needs: [login-container]
|
||||
with:
|
||||
login_build_image: ${{ needs.login-container.outputs.login_build_image }}
|
||||
|
||||
e2e:
|
||||
uses: ./.github/workflows/e2e.yml
|
||||
needs: [compile]
|
||||
@@ -121,6 +127,7 @@ jobs:
|
||||
lint,
|
||||
container,
|
||||
login-container,
|
||||
login-integration-test,
|
||||
e2e,
|
||||
]
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
|
19
.github/workflows/lint.yml
vendored
19
.github/workflows/lint.yml
vendored
@@ -53,14 +53,21 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dev Container CLI
|
||||
run: npm install -g @devcontainers/cli@0.80.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Run lint and unit tests in dev container
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
configFile: .devcontainer/turbo-lint-unit/devcontainer.json
|
||||
runCmd: echo "Successfully ran lint and unit tests in dev container postStartCommand"
|
||||
- name: Lint and Unit Test All JavaScript Code
|
||||
run: npm run devcontainer:lint-unit
|
||||
- name: Fix Failures
|
||||
if: failure()
|
||||
run: |
|
||||
echo "Reproduce this check locally:"
|
||||
echo "npm run devcontainer:lint-unit"
|
||||
echo "If you have pnpm installed, most linting errors can be fixed automatically:"
|
||||
echo "pnpm turbo lint:fix"
|
||||
echo "In other cases, you can open the dev container called \"Turbo Lint and Unit Tests\"."
|
||||
echo "You will have the same environment as the pipeline check as well as some guidance on how to fix the errors."
|
||||
|
||||
core:
|
||||
name: core
|
||||
|
15
.github/workflows/login-container.yml
vendored
15
.github/workflows/login-container.yml
vendored
@@ -12,8 +12,8 @@ on:
|
||||
type: string
|
||||
outputs:
|
||||
login_build_image:
|
||||
description: 'The full image tag of the standalone login image'
|
||||
value: '${{ inputs.login_build_image_name }}:${{ github.sha }}'
|
||||
description: 'The full image tag of the standalone login image'
|
||||
value: ${{ inputs.login_build_image_name }}:${{ github.sha }}
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
@@ -30,6 +30,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
outputs:
|
||||
login_build_image: ${{ steps.short-sha.outputs.login_build_image }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Login meta
|
||||
@@ -41,7 +43,7 @@ jobs:
|
||||
annotations: |
|
||||
manifest:org.opencontainers.image.licenses=MIT
|
||||
tags: |
|
||||
type=sha,prefix=,suffix=,format=long
|
||||
type=sha,prefix=,format=long
|
||||
- name: Login to Docker registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
@@ -49,6 +51,7 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Set up Docker Buildx
|
||||
id: setup-buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Bake login multi-arch
|
||||
uses: docker/bake-action@v6
|
||||
@@ -58,13 +61,9 @@ jobs:
|
||||
source: .
|
||||
push: true
|
||||
provenance: true
|
||||
sbom: true
|
||||
targets: login-standalone
|
||||
set: |
|
||||
*.cache-from=type=gha
|
||||
*.cache-to=type=gha,mode=max
|
||||
files: |
|
||||
./apps/login/docker-bake.hcl
|
||||
./apps/login/docker-bake-release.hcl
|
||||
${{ github.event_name == 'workflow_dispatch' && './apps/login/docker-bake-release.hcl' || '' }}
|
||||
./docker-bake.hcl
|
||||
cwd://${{ steps.login-meta.outputs.bake-file }}
|
||||
|
58
.github/workflows/login-integration-test.yml
vendored
Normal file
58
.github/workflows/login-integration-test.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
name: Integration test core
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
login_build_image:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
login-integration-test:
|
||||
name: login-integration-test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dev Container CLI
|
||||
run: npm install -g @devcontainers/cli@0.80.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Pull Login Build Image
|
||||
run: docker compose --file .devcontainer/login-integration/docker-compose.yaml pull
|
||||
env:
|
||||
LOGIN_TAG: ${{ inputs.login_build_image }}
|
||||
- name: Run Integration Tests against the Login and a Mocked Zitadel API
|
||||
run: npm run devcontainer:integration:login
|
||||
env:
|
||||
LOGIN_TAG: ${{ inputs.login_build_image }}
|
||||
DOCKER_BUILDKIT: 1
|
||||
- name: Fix Failures
|
||||
if: failure()
|
||||
run: |
|
||||
echo "Reproduce this check locally:"
|
||||
echo "LOGIN_TAG=${{ inputs.login_build_image }} npm run devcontainer:integration:login"
|
||||
echo "To fix the failures, open the dev container called \"Login Integration Tests\"."
|
||||
echo "You will have the same environment as the pipeline check as well as some guidance on how to fix the errors."
|
||||
- name: Show Compose Status
|
||||
if: failure()
|
||||
run: docker compose --file .devcontainer/base/docker-compose.yaml --file .devcontainer/login-integration-ci/docker-compose.yaml ps
|
||||
- name: Print Config
|
||||
if: failure()
|
||||
run: COMPOSE_BAKE=1 docker compose --file .devcontainer/base/docker-compose.yaml --file .devcontainer/login-integration-ci/docker-compose.yaml config login-integration
|
||||
env:
|
||||
LOGIN_TAG: ${{ inputs.login_build_image }}
|
||||
- name: Show Container Logs
|
||||
if: failure()
|
||||
run: docker compose --file .devcontainer/base/docker-compose.yaml --file .devcontainer/login-integration-ci/docker-compose.yaml logs --timestamps --no-color --tail 100 login-integration
|
||||
- name: Inspect All Failed Containers
|
||||
if: failure()
|
||||
run: |
|
||||
docker ps -a --filter "status=exited" --filter "status=created" --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Image}}"
|
||||
for container in $(docker ps -a --filter "status=exited" --filter "status=created" -q); do
|
||||
echo "Inspecting container $container"
|
||||
docker inspect $container || true
|
||||
done
|
102
CONTRIBUTING.md
102
CONTRIBUTING.md
@@ -1,6 +1,5 @@
|
||||
# Contributing to Zitadel
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
Thank you for your interest about how to contribute! As you might know there is more than code to contribute. You can find all information needed to start contributing here.
|
||||
@@ -150,51 +149,19 @@ The API is designed to be used by different clients, such as web applications, m
|
||||
Therefore, the API is designed to be easy to use, consistent, and reliable.
|
||||
Please check out the dedicated [API guidelines](./API_DESIGN.md) page when contributing to the API.
|
||||
|
||||
|
||||
#### <a name="dev-containers"></>Developing Zitadel with Dev Containers
|
||||
|
||||
You can use dev containers if you'd like to make sure you have the same development environment like the corresponding GitHub PR checks use.
|
||||
The following dev containers are available:
|
||||
|
||||
- **.devcontainer/base/devcontainer.json**: Contains everything you need to run whatever you want.
|
||||
- **.devcontainer/turbo-lint-unit/devcontainer.json**: Runs a dev container that executes frontent linting and unit tests and then exits. This is useful to reproduce the corresponding GitHub PR check.
|
||||
- **.devcontainer/turbo-lint-unit-debug/devcontainer.json**: Runs a dev container that executes frontent linting and unit tests in watch mode. You can fix the errors right away and have immediate feedback.
|
||||
- **.devcontainer/login-integration/devcontainer.json**: Runs a dev container that executes login integration tests and then exits. This is useful to reproduce the corresponding GitHub PR check.
|
||||
- **.devcontainer/login-integration-debug/devcontainer.json**: Runs a dev container that spins up the login in a hot-reloading dev server and executes login integration tests interactively. You can fix the errors right away and have immediate feedback.
|
||||
|
||||
You can also run the GitHub PR checks locally in dev containers without having to connect to a dev container.
|
||||
|
||||
|
||||
The following pnpm commands use the [devcontainer CLI](https://github.com/devcontainers/cli/) and exit when the checks are done.
|
||||
The minimal system requirements are having Docker and the devcontainers CLI installed.
|
||||
If you don't have the node_modules installed already, you need to install the devcontainers CLI manually. Run `npm i -g @devcontainers/cli`. Alternatively, the [official Microsoft VS Code extension for Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) offers a command `Dev Containers: Install devcontainer CLI`
|
||||
|
||||
|
||||
```bash
|
||||
npm run devcontainer:lint-unit
|
||||
npm run devcontainer:integration:login
|
||||
```
|
||||
|
||||
If you don't have NPM installed, copy and execute the scripts from the package.json directly.
|
||||
|
||||
To connect to a dev container to have full IDE support, follow the instructions provided by your code editor/IDE to initiate the dev container.
|
||||
This typically involves opening the "Command Palette" or similar functionality and searching for commands related to "Dev Containers" or "Remote Containers".
|
||||
The quick start guide for VS Code can found [here](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container)
|
||||
|
||||
For example, to build and run the Zitadel binary in a dev container, connect your IDE to the dev container described in .devcontainer/base/devcontainer.json.
|
||||
Run the following commands inside the container to start Zitadel.
|
||||
|
||||
```bash
|
||||
make compile && ./zitadel start-from-init --masterkey MasterkeyNeedsToHave32Characters --tlsMode disabled
|
||||
```
|
||||
|
||||
Zitadel serves traffic as soon as you can see the following log line:
|
||||
|
||||
`INFO[0001] server is listening on [::]:8080`
|
||||
|
||||
## <a name="backend"></a>Contribute Backend Code
|
||||
|
||||
|
||||
|
||||
### <a name="backend-requirements"></a> Backend Requirements
|
||||
|
||||
By executing the commands from this section, you run everything you need to develop the Zitadel backend locally.
|
||||
|
||||
> [!INFO]
|
||||
> Some [dev containers are available](dev-containers) for remote development with docker and pipeline debugging in isolated environments.
|
||||
> If you don't want to use one of the dev containers, you can develop the backend components directly on your local machine.
|
||||
> To do so, proceed with installing the necessary dependencies.
|
||||
|
||||
Using [Docker Compose](https://docs.docker.com/compose/), you run a [PostgreSQL](https://www.postgresql.org/download/) on your local machine.
|
||||
With [make](https://www.gnu.org/software/make/), you build a debuggable Zitadel binary and run it using [delve](https://github.com/go-delve/delve).
|
||||
Then, you test your changes via the console your binary is serving at http://<span because="breaks the link"></span>localhost:8080 and by verifying the database.
|
||||
@@ -208,6 +175,8 @@ The commands in this section are tested against the following software versions:
|
||||
- [Go version 1.22](https://go.dev/doc/install)
|
||||
- [Delve 1.9.1](https://github.com/go-delve/delve/tree/v1.9.1/Documentation/installation)
|
||||
|
||||
### <a name="build-and-run-zitadel"></a>Build and Run Zitadel
|
||||
|
||||
Make some changes to the source code, then run the database locally.
|
||||
|
||||
```bash
|
||||
@@ -588,6 +557,48 @@ For the turbo commands, check your options with `pnpm turbo --help`
|
||||
| `pnpm turbo down` | Remove containers and volumes | Shut down containers from the integration test setup `pnpm turbo down` |
|
||||
| `pnpm turbo clean` | Remove downloaded dependencies and other generated files | Remove generated docs `pnpm turbo clean --filter zitadel-docs` |
|
||||
|
||||
## <a name="dev-containers"></>Developing Zitadel with Dev Containers
|
||||
|
||||
You can use dev containers if you'd like to make sure you have the same development environment like the corresponding GitHub PR checks use.
|
||||
The following dev containers are available:
|
||||
|
||||
- **.devcontainer/base/devcontainer.json**: Contains everything you need to run whatever you want.
|
||||
- **.devcontainer/turbo-lint-unit/devcontainer.json**: Runs a dev container that executes frontent linting and unit tests and then exits. This is useful to reproduce the corresponding GitHub PR check.
|
||||
- **.devcontainer/turbo-lint-unit-debug/devcontainer.json**: Runs a dev container that executes frontent linting and unit tests in watch mode. You can fix the errors right away and have immediate feedback.
|
||||
- **.devcontainer/login-integration/devcontainer.json**: Runs a dev container that executes login integration tests and then exits. This is useful to reproduce the corresponding GitHub PR check.
|
||||
- **.devcontainer/login-integration-debug/devcontainer.json**: Runs a dev container that spins up the login in a hot-reloading dev server and executes login integration tests interactively. You can fix the errors right away and have immediate feedback.
|
||||
|
||||
You can also run the GitHub PR checks locally in dev containers without having to connect to a dev container.
|
||||
|
||||
|
||||
The following pnpm commands use the [devcontainer CLI](https://github.com/devcontainers/cli/) and exit when the checks are done.
|
||||
The minimal system requirements are having Docker and the devcontainers CLI installed.
|
||||
If you don't have the node_modules installed already, you need to install the devcontainers CLI manually. Run `npm i -g @devcontainers/cli@0.80.0`. Alternatively, the [official Microsoft VS Code extension for Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) offers a command `Dev Containers: Install devcontainer CLI`
|
||||
|
||||
|
||||
```bash
|
||||
npm run devcontainer:lint-unit
|
||||
npm run devcontainer:integration:login
|
||||
```
|
||||
|
||||
If you don't have NPM installed, copy and execute the scripts from the package.json directly.
|
||||
|
||||
To connect to a dev container to have full IDE support, follow the instructions provided by your code editor/IDE to initiate the dev container.
|
||||
This typically involves opening the "Command Palette" or similar functionality and searching for commands related to "Dev Containers" or "Remote Containers".
|
||||
The quick start guide for VS Code can found [here](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container)
|
||||
|
||||
For example, to build and run the Zitadel binary in a dev container, connect your IDE to the dev container described in .devcontainer/base/devcontainer.json.
|
||||
Run the following commands inside the container to start Zitadel.
|
||||
|
||||
```bash
|
||||
make compile && ./zitadel start-from-init --masterkey MasterkeyNeedsToHave32Characters --tlsMode disabled
|
||||
```
|
||||
|
||||
Zitadel serves traffic as soon as you can see the following log line:
|
||||
|
||||
`INFO[0001] server is listening on [::]:8080`
|
||||
|
||||
|
||||
## <a name="contribute-translations"></a>Contribute Translations
|
||||
|
||||
Zitadel loads translations from four files:
|
||||
@@ -608,11 +619,6 @@ You also have to add some changes to the following files:
|
||||
- [Customized Text Docs](./docs/docs/guides/manage/customize/texts.md)
|
||||
- [Add language option](./internal/api/ui/login/static/templates/external_not_found_option.html)
|
||||
|
||||
## Want to start Zitadel?
|
||||
|
||||
You can find an installation guide for all the different environments here:
|
||||
[https://zitadel.com/docs/self-hosting/deploy/overview](https://zitadel.com/docs/self-hosting/deploy/overview)
|
||||
|
||||
## **Did you find a security flaw?**
|
||||
|
||||
- Please read [Security Policy](./SECURITY.md).
|
||||
|
@@ -1,5 +1,6 @@
|
||||
NEXT_PUBLIC_BASE_PATH="/ui/v2/login"
|
||||
ZITADEL_API_URL=http://mock-zitadel:22222
|
||||
ZITADEL_API_URL=http://localhost:22222
|
||||
ZITADEL_SERVICE_USER_TOKEN="yolo"
|
||||
EMAIL_VERIFICATION=true
|
||||
DEBUG=true
|
||||
PORT=3001
|
||||
NEXT_PUBLIC_BASE_PATH=/ui/v2/login
|
||||
|
2
apps/login/.gitignore
vendored
2
apps/login/.gitignore
vendored
@@ -2,6 +2,7 @@ custom-config.js
|
||||
.env*.local
|
||||
standalone
|
||||
tsconfig.tsbuildinfo
|
||||
cypress
|
||||
|
||||
.DS_Store
|
||||
node_modules
|
||||
@@ -11,6 +12,5 @@ node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
.env
|
||||
.vscode
|
||||
/blob-report/
|
||||
|
@@ -3,21 +3,21 @@ FROM node:20-alpine AS base
|
||||
FROM base AS build
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@9.1.2 --activate && \
|
||||
apk update && apk add --no-cache && \
|
||||
RUN corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@10.13.1 --activate && \
|
||||
apk update && \
|
||||
rm -rf /var/cache/apk/*
|
||||
WORKDIR /app
|
||||
COPY pnpm-lock.yaml ./
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm fetch --frozen-lockfile
|
||||
COPY package.json ./
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile --prod
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
||||
COPY . .
|
||||
RUN pnpm build:login:standalone
|
||||
|
||||
FROM scratch AS build-out
|
||||
COPY --from=build /app/.next/standalone /
|
||||
COPY --from=build /app/.next/static /.next/static
|
||||
COPY --from=build /app/public /public
|
||||
COPY public public
|
||||
|
||||
FROM base AS login-standalone
|
||||
WORKDIR /runtime
|
||||
@@ -25,12 +25,13 @@ RUN addgroup --system --gid 1001 nodejs && \
|
||||
adduser --system --uid 1001 nextjs
|
||||
# If /.env-file/.env is mounted into the container, its variables are made available to the server before it starts up.
|
||||
RUN mkdir -p /.env-file && touch /.env-file/.env && chown -R nextjs:nodejs /.env-file
|
||||
COPY ./scripts/ ./
|
||||
COPY --chown=nextjs:nodejs ./scripts/ ./
|
||||
COPY --chown=nextjs:nodejs --from=build-out / ./
|
||||
USER nextjs
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0" \
|
||||
NEXT_PUBLIC_BASE_PATH="/ui/v2/login" \
|
||||
PORT=3000
|
||||
# TODO: Check healthy, not ready
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD ["/bin/sh", "-c", "node ./healthcheck.js http://localhost:${PORT}/ui/v2/login/healthy"]
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
CMD ["/bin/sh", "-c", "node /runtime/healthcheck.js http://localhost:${PORT}/ui/v2/login/healthy"]
|
||||
ENTRYPOINT ["/runtime/entrypoint.sh"]
|
||||
|
@@ -8,7 +8,8 @@
|
||||
!next.config.mjs
|
||||
!next-env-vars.d.ts
|
||||
!next-env.d.ts
|
||||
!tailwind.config.js
|
||||
!tailwind.config.mjs
|
||||
!postcss.config.cjs
|
||||
!tsconfig.json
|
||||
!package.json
|
||||
!pnpm-lock.yaml
|
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "login-test-acceptance",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test:acceptance": "dotenv -e ../login/.env.test.local playwright",
|
||||
"test:acceptance:setup": "cd ../.. && make login_test_acceptance_setup_env && NODE_ENV=test turbo run test:acceptance:setup:dev",
|
||||
"test:acceptance:setup:dev": "cd ../.. && make login_test_acceptance_setup_dev",
|
||||
"clean": "rm -rf .turbo node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^9.7.0",
|
||||
"@otplib/core": "^12.0.0",
|
||||
"@otplib/plugin-crypto": "^12.0.0",
|
||||
"@otplib/plugin-thirty-two": "^12.0.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"dotenv-cli": "^8.0.0",
|
||||
"gaxios": "^7.1.0",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
@@ -2,11 +2,11 @@ import { defineConfig } from "cypress";
|
||||
|
||||
export default defineConfig({
|
||||
reporter: "list",
|
||||
|
||||
video: true,
|
||||
e2e: {
|
||||
baseUrl: process.env.LOGIN_BASE_URL || "http://localhost:3001/ui/v2/login",
|
||||
specPattern: "integration/**/*.cy.{js,jsx,ts,tsx}",
|
||||
supportFile: "support/e2e.{js,jsx,ts,tsx}",
|
||||
specPattern: "integration/integration/**/*.cy.{js,jsx,ts,tsx}",
|
||||
supportFile: "integration/support/e2e.{js,jsx,ts,tsx}",
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
@@ -1,8 +1,10 @@
|
||||
FROM bufbuild/buf:1.54.0 AS proto-files
|
||||
RUN buf export https://github.com/envoyproxy/protoc-gen-validate.git --path validate --output /proto-files && \
|
||||
buf export https://github.com/grpc-ecosystem/grpc-gateway.git --path protoc-gen-openapiv2 --output /proto-files && \
|
||||
buf export https://github.com/googleapis/googleapis.git --path protos/zitadelgoogle/api/annotations.proto --path google/api/http.proto --path google/api/field_behavior.proto --output /proto-files && \
|
||||
buf export https://github.com/zitadel/zitadel.git --path ./proto/zitadel --output /proto-files
|
||||
FROM bufbuild/buf:1.54.0 AS dependencies
|
||||
RUN buf export https://github.com/envoyproxy/protoc-gen-validate.git --path validate --output /proto && \
|
||||
buf export https://github.com/grpc-ecosystem/grpc-gateway.git --path protoc-gen-openapiv2 --output /proto && \
|
||||
buf export https://github.com/googleapis/googleapis.git --path google/api/annotations.proto --path google/api/http.proto --path google/api/field_behavior.proto --output /proto
|
||||
|
||||
FROM bufbuild/buf:1.54.0 AS zitadel-protos
|
||||
RUN buf export https://github.com/zitadel/zitadel.git --path ./proto/zitadel --output /zitadel
|
||||
|
||||
FROM golang:1.20.5-alpine3.18 AS mock-zitadel
|
||||
|
||||
@@ -10,6 +12,7 @@ RUN go install github.com/eliobischof/grpc-mock/cmd/grpc-mock@01b09f60db1b501178
|
||||
|
||||
COPY mocked-services.cfg .
|
||||
COPY initial-stubs initial-stubs
|
||||
COPY --from=proto-files /proto-files/ ./
|
||||
COPY --from=dependencies /proto/ ./
|
||||
COPY --from=zitadel-protos /zitadel/ ./zitadel/
|
||||
|
||||
ENTRYPOINT [ "sh", "-c", "grpc-mock -v 1 -proto $(tr '\n' ',' < ./mocked-services.cfg) -stub-dir ./initial-stubs -mock-addr :22222" ]
|
||||
|
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
@@ -22,22 +22,22 @@ describe("verify invite", () => {
|
||||
user: {
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
human: {
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
profile: {
|
||||
givenName: "John",
|
||||
familyName: "Doe",
|
||||
avatarUrl: "https://zitadel.com/avatar.jpg",
|
||||
avatarUrl: "https://example.com/avatar.jpg",
|
||||
},
|
||||
email: {
|
||||
email: "john@zitadel.com",
|
||||
email: "john@example.com",
|
||||
isVerified: false,
|
||||
},
|
||||
},
|
||||
@@ -68,7 +68,7 @@ describe("verify invite", () => {
|
||||
factors: {
|
||||
user: {
|
||||
id: "221394658884845598",
|
||||
loginName: "john@zitadel.com",
|
||||
loginName: "john@example.com",
|
||||
},
|
||||
password: undefined,
|
||||
webAuthN: undefined,
|
||||
@@ -93,7 +93,7 @@ describe("verify invite", () => {
|
||||
stub("zitadel.user.v2.UserService", "VerifyInviteCode");
|
||||
|
||||
cy.visit("/verify?userId=221394658884845598&code=abc&invite=true");
|
||||
cy.url({ timeout: 10_000 }).should("include", Cypress.config().baseUrl + "/authenticator/set");
|
||||
cy.url().should("include", Cypress.config().baseUrl + "/authenticator/set");
|
||||
});
|
||||
|
||||
it("shows an error if invite code validation failed", () => {
|
||||
|
@@ -33,7 +33,7 @@ describe("login", () => {
|
||||
factors: {
|
||||
user: {
|
||||
id: "221394658884845598",
|
||||
loginName: "john@zitadel.com",
|
||||
loginName: "john@example.com",
|
||||
},
|
||||
password: undefined,
|
||||
webAuthN: undefined,
|
||||
@@ -64,22 +64,22 @@ describe("login", () => {
|
||||
{
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
human: {
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
profile: {
|
||||
givenName: "John",
|
||||
familyName: "Doe",
|
||||
avatarUrl: "https://zitadel.com/avatar.jpg",
|
||||
avatarUrl: "https://example.com/avatar.jpg",
|
||||
},
|
||||
email: {
|
||||
email: "john@zitadel.com",
|
||||
email: "john@example.com",
|
||||
isVerified: true,
|
||||
},
|
||||
},
|
||||
@@ -94,8 +94,8 @@ describe("login", () => {
|
||||
});
|
||||
});
|
||||
it("should redirect a user with password authentication to /password", () => {
|
||||
cy.visit("/loginname?loginName=john%40zitadel.com&submit=true");
|
||||
cy.url({ timeout: 10_000 }).should("include", Cypress.config().baseUrl + "/password");
|
||||
cy.visit("/loginname?loginName=john%40example.com&submit=true");
|
||||
cy.url({ timeout: 5 * 60_000 }).should("include", Cypress.config().baseUrl + "/password");
|
||||
});
|
||||
describe("with passkey prompt", () => {
|
||||
beforeEach(() => {
|
||||
@@ -112,8 +112,8 @@ describe("login", () => {
|
||||
});
|
||||
});
|
||||
// it("should prompt a user to setup passwordless authentication if passkey is allowed in the login settings", () => {
|
||||
// cy.visit("/loginname?loginName=john%40zitadel.com&submit=true");
|
||||
// cy.location("pathname", { timeout: 10_000 }).should("eq", "/password");
|
||||
// cy.visit("/loginname?loginName=john%40example.com&submit=true");
|
||||
// cy.location("pathname", { timeout: 5 * 60_000 }).should("eq", "/password");
|
||||
// cy.get('input[type="password"]').focus().type("MyStrongPassword!1");
|
||||
// cy.get('button[type="submit"]').click();
|
||||
// cy.location("pathname", { timeout: 10_000 }).should(
|
||||
@@ -134,22 +134,22 @@ describe("login", () => {
|
||||
{
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
human: {
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
profile: {
|
||||
givenName: "John",
|
||||
familyName: "Doe",
|
||||
avatarUrl: "https://zitadel.com/avatar.jpg",
|
||||
avatarUrl: "https://example.com/avatar.jpg",
|
||||
},
|
||||
email: {
|
||||
email: "john@zitadel.com",
|
||||
email: "john@example.com",
|
||||
isVerified: true,
|
||||
},
|
||||
},
|
||||
@@ -165,8 +165,8 @@ describe("login", () => {
|
||||
});
|
||||
|
||||
it("should redirect a user with passwordless authentication to /passkey", () => {
|
||||
cy.visit("/loginname?loginName=john%40zitadel.com&submit=true");
|
||||
cy.url({ timeout: 10_000 }).should("include", Cypress.config().baseUrl + "/passkey");
|
||||
cy.visit("/loginname?loginName=john%40example.com&submit=true");
|
||||
cy.url().should("include", Cypress.config().baseUrl + "/passkey");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -15,7 +15,7 @@ describe("register idps", () => {
|
||||
cy.visit("/idp");
|
||||
cy.get('button[e2e="google"]').click();
|
||||
cy.origin(IDP_URL, { args: IDP_URL }, (url) => {
|
||||
cy.location("href", { timeout: 10_000 }).should("eq", url);
|
||||
cy.location("href").should("eq", url);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -48,7 +48,7 @@ describe("register", () => {
|
||||
factors: {
|
||||
user: {
|
||||
id: "221394658884845598",
|
||||
loginName: "john@zitadel.com",
|
||||
loginName: "john@example.com",
|
||||
},
|
||||
password: undefined,
|
||||
webAuthN: undefined,
|
||||
@@ -64,10 +64,10 @@ describe("register", () => {
|
||||
cy.visit("/register");
|
||||
cy.get('input[data-testid="firstname-text-input"]').focus().type("John");
|
||||
cy.get('input[data-testid="lastname-text-input"]').focus().type("Doe");
|
||||
cy.get('input[data-testid="email-text-input"]').focus().type("john@zitadel.com");
|
||||
cy.get('input[data-testid="email-text-input"]').focus().type("john@example.com");
|
||||
cy.get('input[type="checkbox"][value="privacypolicy"]').check();
|
||||
cy.get('input[type="checkbox"][value="tos"]').check();
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.url({ timeout: 10_000 }).should("include", Cypress.config().baseUrl + "/passkey/set");
|
||||
cy.url().should("include", Cypress.config().baseUrl + "/passkey/set");
|
||||
});
|
||||
});
|
||||
|
@@ -24,22 +24,22 @@ describe("verify email", () => {
|
||||
user: {
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
human: {
|
||||
userId: "221394658884845598",
|
||||
state: 1,
|
||||
username: "john@zitadel.com",
|
||||
loginNames: ["john@zitadel.com"],
|
||||
preferredLoginName: "john@zitadel.com",
|
||||
username: "john@example.com",
|
||||
loginNames: ["john@example.com"],
|
||||
preferredLoginName: "john@example.com",
|
||||
profile: {
|
||||
givenName: "John",
|
||||
familyName: "Doe",
|
||||
avatarUrl: "https://zitadel.com/avatar.jpg",
|
||||
avatarUrl: "https://example.com/avatar.jpg",
|
||||
},
|
||||
email: {
|
||||
email: "john@zitadel.com",
|
||||
email: "john@example.com",
|
||||
isVerified: false, // email is not verified yet
|
||||
},
|
||||
},
|
||||
@@ -70,7 +70,7 @@ describe("verify email", () => {
|
||||
factors: {
|
||||
user: {
|
||||
id: "221394658884845598",
|
||||
loginName: "john@zitadel.com",
|
||||
loginName: "john@example.com",
|
||||
},
|
||||
password: undefined,
|
||||
webAuthN: undefined,
|
||||
@@ -90,6 +90,6 @@ describe("verify email", () => {
|
||||
// TODO: Avoid uncaught exception in application
|
||||
cy.once("uncaught:exception", () => false);
|
||||
cy.visit("/verify?userId=221394658884845598&code=abc");
|
||||
cy.contains("Could not verify email", { timeout: 10_000 });
|
||||
cy.contains("Could not verify email");
|
||||
});
|
||||
});
|
||||
|
@@ -1,4 +1,4 @@
|
||||
const url = Cypress.env("CORE_MOCK_STUBS_URL") || "http://mock-zitadel:22220/v1/stubs";
|
||||
const url = Cypress.env("CORE_MOCK_STUBS_URL") || "http://localhost:22220/v1/stubs";
|
||||
|
||||
function removeStub(service: string, method: string) {
|
||||
return cy.request({
|
||||
|
@@ -4,5 +4,5 @@
|
||||
"lib": ["es5", "dom"],
|
||||
"types": ["cypress", "node"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
"include": ["**/*.ts", "../cypress.config.ts"]
|
||||
}
|
||||
|
2
apps/login/next-env-vars.d.ts
vendored
2
apps/login/next-env-vars.d.ts
vendored
@@ -27,6 +27,8 @@ declare namespace NodeJS {
|
||||
/**
|
||||
* Optional: custom request headers to be added to every request
|
||||
* Split by comma, key value pairs separated by colon
|
||||
* For example: to call the Zitadel API at an internal address, you can set:
|
||||
* `CUSTOM_REQUEST_HEADERS=Host:http://zitadel-internal:8080`
|
||||
*/
|
||||
CUSTOM_REQUEST_HEADERS?: string;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"packageManager": "pnpm@9.1.2+sha256.19c17528f9ca20bd442e4ca42f00f1b9808a9cb419383cd04ba32ef19322aba7",
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"name": "@zitadel/login",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -15,8 +15,7 @@
|
||||
"test:unit": "vitest --run",
|
||||
"lint-staged": "lint-staged",
|
||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
|
||||
"test:integration:login": "cypress run",
|
||||
"test:integration:login:debug": "cypress open",
|
||||
"test:integration:login": "wait-on --simultaneous 1 http://localhost:3001/ui/v2/login/verify?userId=221394658884845598&code=abc && cypress run",
|
||||
"test:acceptance": "dotenv -e ../login/.env.test.local playwright",
|
||||
"test:acceptance:setup": "cd ../.. && make login_test_acceptance_setup_env && NODE_ENV=test turbo run test:acceptance:setup:dev",
|
||||
"test:acceptance:setup:dev": "cd ../.. && make login_test_acceptance_setup_dev"
|
||||
@@ -54,6 +53,11 @@
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.23.0",
|
||||
"@bufbuild/buf": "^1.53.0",
|
||||
"@faker-js/faker": "^9.7.0",
|
||||
"@otplib/core": "^12.0.0",
|
||||
"@otplib/plugin-crypto": "^12.0.0",
|
||||
"@otplib/plugin-thirty-two": "^12.0.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@types/ms": "2.1.0",
|
||||
@@ -67,34 +71,30 @@
|
||||
"@vercel/git-hooks": "1.0.0",
|
||||
"@vitejs/plugin-react": "^4.4.1",
|
||||
"autoprefixer": "10.4.21",
|
||||
"concurrently": "^9.1.2",
|
||||
"cypress": "^14.5.2",
|
||||
"dotenv-cli": "^8.0.0",
|
||||
"env-cmd": "^10.0.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "15.4.0-canary.86",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"gaxios": "^7.1.0",
|
||||
"grpc-tools": "1.13.0",
|
||||
"jsdom": "^26.1.0",
|
||||
"lint-staged": "15.5.1",
|
||||
"make-dir-cli": "4.0.0",
|
||||
"nodemon": "^3.1.9",
|
||||
"postcss": "8.5.3",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-organize-imports": "^3.2.0",
|
||||
"prettier-plugin-tailwindcss": "0.6.11",
|
||||
"sass": "^1.87.0",
|
||||
"start-server-and-test": "^2.0.11",
|
||||
"tailwindcss": "3.4.14",
|
||||
"ts-proto": "^2.7.0",
|
||||
"typescript": "^5.8.3",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^2.0.0",
|
||||
"concurrently": "^9.1.2",
|
||||
"cypress": "^14.5.2",
|
||||
"dotenv-cli": "^8.0.0",
|
||||
"env-cmd": "^10.0.0",
|
||||
"nodemon": "^3.1.9",
|
||||
"start-server-and-test": "^2.0.11",
|
||||
"@faker-js/faker": "^9.7.0",
|
||||
"@otplib/core": "^12.0.0",
|
||||
"@otplib/plugin-crypto": "^12.0.0",
|
||||
"@otplib/plugin-thirty-two": "^12.0.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"gaxios": "^7.1.0"
|
||||
"wait-on": "^7.2.0"
|
||||
}
|
||||
}
|
9151
apps/login/pnpm-lock.yaml
generated
Normal file
9151
apps/login/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,57 @@
|
||||
{
|
||||
"extends": ["//"],
|
||||
"extends": [
|
||||
"//"
|
||||
],
|
||||
"tasks": {
|
||||
"build": {
|
||||
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
|
||||
"dependsOn": ["@zitadel/client#build"]
|
||||
"outputs": [
|
||||
"dist/**",
|
||||
".next/**",
|
||||
"!.next/cache/**"
|
||||
],
|
||||
"dependsOn": [
|
||||
"@zitadel/client#build"
|
||||
]
|
||||
},
|
||||
"build:login:standalone": {
|
||||
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
|
||||
"dependsOn": ["@zitadel/client#build"]
|
||||
"outputs": [
|
||||
"dist/**",
|
||||
".next/**",
|
||||
"!.next/cache/**"
|
||||
],
|
||||
"dependsOn": [
|
||||
"@zitadel/client#build"
|
||||
]
|
||||
},
|
||||
"dev": {
|
||||
"dependsOn": ["@zitadel/client#build"]
|
||||
"persistent": true,
|
||||
"cache": false,
|
||||
"dependsOn": [
|
||||
"@zitadel/client#build"
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": ["@zitadel/client#build"]
|
||||
"dependsOn": [
|
||||
"@zitadel/client#build"
|
||||
]
|
||||
},
|
||||
"test:unit": {
|
||||
"dependsOn": ["@zitadel/client#build"]
|
||||
"dependsOn": [
|
||||
"@zitadel/client#build"
|
||||
]
|
||||
},
|
||||
"test:integration:login": {
|
||||
"inputs": [
|
||||
".next/**",
|
||||
"!.next/cache/**",
|
||||
"integration/integration/**",
|
||||
"integration/support/**",
|
||||
"cypress.config.ts"
|
||||
],
|
||||
"outputs": [
|
||||
"cypress/videos/**",
|
||||
"cypress/screenshots/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,34 +1,43 @@
|
||||
FROM node:20-alpine AS base
|
||||
FROM node:20-alpine AS runtime
|
||||
|
||||
FROM base AS build
|
||||
FROM runtime AS pnpm-base
|
||||
RUN apk add --no-cache libc6-compat
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@9.1.2 --activate && \
|
||||
apk update && apk add --no-cache && \
|
||||
rm -rf /var/cache/apk/*
|
||||
WORKDIR /app
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm fetch --frozen-lockfile \
|
||||
--filter @zitadel/login \
|
||||
--filter @zitadel/client \
|
||||
--filter @zitadel/proto
|
||||
COPY package.json ./
|
||||
COPY apps/login/package.json ./apps/login/package.json
|
||||
COPY packages/zitadel-proto/package.json ./packages/zitadel-proto/package.json
|
||||
COPY packages/zitadel-client/package.json ./packages/zitadel-client/package.json
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile \
|
||||
--filter @zitadel/login \
|
||||
--filter @zitadel/client \
|
||||
--filter @zitadel/proto
|
||||
RUN corepack enable && corepack prepare pnpm@10.13.1 --activate
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
||||
pnpm add -g turbo@2.5.5
|
||||
|
||||
FROM pnpm-base AS pruner
|
||||
WORKDIR /prune
|
||||
COPY . .
|
||||
RUN pnpm turbo build:login:standalone
|
||||
RUN pnpm turbo prune @zitadel/login @zitadel/client @zitadel/proto --docker
|
||||
|
||||
FROM pnpm-base AS installer
|
||||
WORKDIR /install
|
||||
COPY --from=pruner /prune/out/pnpm-lock.yaml ./
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
||||
pnpm fetch --frozen-lockfile
|
||||
COPY --from=pruner /prune/out/json/ .
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
||||
pnpm install --frozen-lockfile --ignore-scripts
|
||||
|
||||
FROM pnpm-base AS builder
|
||||
WORKDIR /build
|
||||
COPY --from=installer /install/ .
|
||||
COPY --from=pruner /prune/out/full/ .
|
||||
COPY proto ./proto
|
||||
ENV CI=true
|
||||
RUN --mount=type=cache,id=turbo,target=/build/.turbo/cache \
|
||||
--mount=type=cache,id=next,target=/build/apps/login/.next/cache \
|
||||
pnpm turbo build:login:standalone --cache-dir=/build/.turbo/cache
|
||||
|
||||
FROM scratch AS build-out
|
||||
COPY /apps/login/public ./apps/login/public
|
||||
COPY --from=build /app/apps/login/.next/standalone ./
|
||||
COPY --from=build /app/apps/login/.next/static ./apps/login/.next/static
|
||||
COPY --from=builder /build/apps/login/.next/standalone ./
|
||||
COPY --from=builder /build/apps/login/.next/static ./apps/login/.next/static
|
||||
|
||||
FROM base AS login-standalone
|
||||
FROM runtime AS login-standalone
|
||||
WORKDIR /runtime
|
||||
RUN addgroup --system --gid 1001 nodejs && \
|
||||
adduser --system --uid 1001 nextjs
|
||||
@@ -36,10 +45,11 @@ RUN addgroup --system --gid 1001 nodejs && \
|
||||
RUN mkdir -p /.env-file && touch /.env-file/.env && chown -R nextjs:nodejs /.env-file
|
||||
COPY --chown=nextjs:nodejs apps/login/scripts ./
|
||||
COPY --chown=nextjs:nodejs --from=build-out . .
|
||||
# Debug the final structure
|
||||
USER nextjs
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
ENV PORT=3000
|
||||
# TODO: Check healthy, not ready
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD ["/bin/sh", "-c", "node ./healthcheck.js http://localhost:${PORT}/ui/v2/login/healthy"]
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
CMD ["/bin/sh", "-c", "node /runtime/healthcheck.js http://localhost:${PORT}/ui/v2/login/healthy"]
|
||||
ENTRYPOINT ["/runtime/entrypoint.sh"]
|
||||
|
@@ -524,7 +524,7 @@ OIDC:
|
||||
PollInterval: 5s # ZITADEL_OIDC_DEVICEAUTH_POLLINTERVAL
|
||||
UserCode:
|
||||
CharSet: "BCDFGHJKLMNPQRSTVWXZ" # ZITADEL_OIDC_DEVICEAUTH_USERCODE_CHARSET
|
||||
CharAmount: 8 # ZITADEL_OIDC_DEVICEAUTH_USERCODE_CHARARMOUNT
|
||||
CharAmount: 8 # ZITADEL_OIDC_DEVICEAUTH_USERCODE_CHARAMOUNT
|
||||
DashInterval: 4 # ZITADEL_OIDC_DEVICEAUTH_USERCODE_DASHINTERVAL
|
||||
DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_OIDC_DEFAULTLOGINURLV2
|
||||
DefaultLogoutURLV2: "/ui/v2/login/logout?post_logout_redirect=" # ZITADEL_OIDC_DEFAULTLOGOUTURLV2
|
||||
|
@@ -66,18 +66,24 @@
|
||||
|
||||
.type-icon {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.type-button-icon,
|
||||
.type-icon,
|
||||
span {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.type-icon,
|
||||
.type-button-icon {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
> span {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
button[mat-icon-button] {
|
||||
margin-right: 0;
|
||||
|
||||
.type-button-icon {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.trigger-wrapper {
|
||||
|
@@ -6,8 +6,6 @@ target "login-standalone" {
|
||||
target "login-standalone-out" {
|
||||
inherits = ["login-standalone"]
|
||||
target = "build-out"
|
||||
output = [
|
||||
"type=local,dest=.artifacts/login"
|
||||
]
|
||||
output = ["type=local,dest=.artifacts/login"]
|
||||
}
|
||||
|
@@ -184,7 +184,7 @@ https://github.com/zitadel/actions/blob/main/examples/add_metadata.js
|
||||
|
||||
## Use provided fields of identity providers
|
||||
|
||||
If you want to ensure that the data of a user are always update you can automatically update user fields during authentication and safe time of your customers and your team. 🤯
|
||||
If you want to ensure that the data of a user are always up-to-date, you can automatically update user fields during authentication and save time of your customers and your team.
|
||||
|
||||
### Trigger
|
||||
|
||||
|
2
docs/docs/self-hosting/deploy/.gitignore
vendored
2
docs/docs/self-hosting/deploy/.gitignore
vendored
@@ -1 +1 @@
|
||||
login-client-pat
|
||||
*.pat
|
@@ -1,8 +1,6 @@
|
||||
Open your favorite internet browser and navigate to [http://localhost:8080/ui/console](http://localhost:8080/ui/console).
|
||||
This is the default IAM admin users login:
|
||||
- **username**: *zitadel-admin@<span></span>zitadel.localhost*
|
||||
- **password**: *Password1!*
|
||||
Open your favorite internet browser and navigate to http://localhost:8080/ui/console?login_hint=zitadel-admin@zitadel.localhost.
|
||||
Enther the password *Password1!* to log in.
|
||||
|
||||
:::info
|
||||
|
||||
In the above username, replace localhost with your configured external domain, if any. e.g. with *zitadel-admin@<span></span>zitadel.sso.my.domain.tld*
|
||||
In the above login hint in the URL, replace localhost with your configured external domain, if any. e.g. with *zitadel-admin@<span></span>zitadel.sso.my.domain.tld*
|
||||
:::
|
@@ -5,61 +5,45 @@ sidebar_label: Docker Compose
|
||||
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import DockerComposeSource from '!!raw-loader!./docker-compose.yaml'
|
||||
import ExampleZitadelConfigSource from '!!raw-loader!./example-zitadel-config.yaml'
|
||||
import ExampleZitadelSecretsSource from '!!raw-loader!./example-zitadel-secrets.yaml'
|
||||
import ExampleZitadelInitStepsSource from '!!raw-loader!./example-zitadel-init-steps.yaml'
|
||||
import Disclaimer from './_disclaimer.mdx'
|
||||
import DefaultUser from './_defaultuser.mdx'
|
||||
import Next from './_next.mdx'
|
||||
import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.mdx';
|
||||
|
||||
The stack consists of four long-running containers and a couple of short-lived containers:
|
||||
- A [Traefik](https://doc.traefik.io/traefik/) reverse proxy container with upstream HTTP/2 enabled, issuing a self-signed TLS certificate.
|
||||
- A Login container that is accessible via Traefik at `/ui/v2/login`
|
||||
- A Zitadel container that is accessible via Traefik at all other paths than `/ui/v2/login`.
|
||||
- An insecure [PostgreSQL](https://www.postgresql.org/docs/current/index.html).
|
||||
|
||||
The Traefik container and the login container call the Zitadel container via the internal Docker network at `h2c://zitadel:8080`
|
||||
|
||||
The setup is tested against Docker version 28.3.2 and Docker Compose version v2.38.2
|
||||
|
||||
By executing the commands below, you will download the following files:
|
||||
## Docker compose
|
||||
|
||||
By executing the commands below, you will download the following file:
|
||||
|
||||
<details>
|
||||
<summary>docker-compose.yaml</summary>
|
||||
<CodeBlock language="yaml">{DockerComposeSource}</CodeBlock>
|
||||
</details>
|
||||
<details>
|
||||
<summary>example-zitadel-config.yaml</summary>
|
||||
<CodeBlock language="yaml">{ExampleZitadelConfigSource}</CodeBlock>
|
||||
</details>
|
||||
<details>
|
||||
<summary>example-zitadel-secrets.yaml</summary>
|
||||
<CodeBlock language="yaml">{ExampleZitadelSecretsSource}</CodeBlock>
|
||||
</details>
|
||||
<details>
|
||||
<summary>example-zitadel-init-steps.yaml</summary>
|
||||
<CodeBlock language="yaml">{ExampleZitadelInitStepsSource}</CodeBlock>
|
||||
</details>
|
||||
|
||||
```bash
|
||||
# Download the docker compose example configuration.
|
||||
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/docker-compose.yaml
|
||||
|
||||
# Download and adjust the example configuration file containing standard configuration.
|
||||
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/example-zitadel-config.yaml
|
||||
|
||||
# Download and adjust the example configuration file containing secret configuration.
|
||||
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/example-zitadel-secrets.yaml
|
||||
|
||||
# Download and adjust the example configuration file containing database initialization configuration.
|
||||
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/deploy/example-zitadel-init-steps.yaml
|
||||
|
||||
# Make sure you have the latest version of the images
|
||||
# Make sure you have the latest image versions
|
||||
docker compose pull
|
||||
|
||||
# Run the containers
|
||||
# Run the PostgreSQL database, the Zitadel API and the Zitadel login.
|
||||
docker compose up
|
||||
```
|
||||
|
||||
Open your favorite internet browser at https://localhost/ui/console?login_hint=zitadel-admin@zitadel.localhost.
|
||||
Your browser warns you about the insecure self-signed TLS certificate. As localhost resolves to your local machine, you can safely proceed.
|
||||
Use the password *Password1!* to log in.
|
||||
<DefaultUser components={props.components} />
|
||||
|
||||
Read more about [the login process](/guides/integrate/login/oidc/login-users).
|
||||
:::info
|
||||
If you ran these commands for an existing instance that still uses the login v1, [create a login client for it to the now running v2 login](/self-hosting/manage/login-client#create-login-client).
|
||||
Move the login client PAT to `./login-client.pat` and restart the login container.
|
||||
```bash
|
||||
docker compose restart login
|
||||
```
|
||||
Now, [enable the Login UI for all users](/self-hosting/manage/login-client#require-login-v2)
|
||||
:::
|
||||
|
||||
<NoteInstanceNotFound/>
|
||||
<Next components={props.components} />
|
||||
<Disclaimer components={props.components} />
|
||||
|
@@ -1,117 +1,98 @@
|
||||
services:
|
||||
|
||||
db:
|
||||
image: postgres:17-alpine
|
||||
zitadel:
|
||||
restart: unless-stopped
|
||||
image: ghcr.io/zitadel/zitadel:latest
|
||||
command: start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
|
||||
environment:
|
||||
- POSTGRES_USER=root
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
networks:
|
||||
- 'storage'
|
||||
ZITADEL_EXTERNALSECURE: false
|
||||
ZITADEL_TLS_ENABLED: false
|
||||
ZITADEL_DATABASE_POSTGRES_HOST: db
|
||||
ZITADEL_DATABASE_POSTGRES_PORT: 5432
|
||||
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
|
||||
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
|
||||
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
|
||||
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
|
||||
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres
|
||||
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres
|
||||
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
|
||||
# By configuring a login client, the setup job creates a user of type machine with the role IAM_LOGIN_CLIENT.
|
||||
# It writes a PAT to the path specified in ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH.
|
||||
# The PAT is passed to the login container via the environment variable ZITADEL_SERVICE_USER_TOKEN_FILE.
|
||||
ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH: /current-dir/login-client.pat
|
||||
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: false
|
||||
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME: login-client
|
||||
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME: Automatically Initialized IAM_LOGIN_CLIENT
|
||||
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE: '2029-01-01T00:00:00Z'
|
||||
ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: true
|
||||
ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_BASEURI: http://localhost:3000/ui/v2/login
|
||||
ZITADEL_OIDC_DEFAULTLOGINURLV2: http://localhost:3000/ui/v2/login/login?authRequest=
|
||||
ZITADEL_OIDC_DEFAULTLOGOUTURLV2: http://localhost:3000/ui/v2/login/logout?post_logout_redirect=
|
||||
ZITADEL_SAML_DEFAULTLOGINURLV2: http://localhost:3000/ui/v2/login/login?samlRequest=
|
||||
# By configuring a machine, the setup job creates a user of type machine with the role IAM_OWNER.
|
||||
# It writes a personal access token (PAT) to the path specified in ZITADEL_FIRSTINSTANCE_PATPATH.
|
||||
# The PAT can be used to provision resources with [Terraform](/docs/guides/manage/terraform-provider), for example.
|
||||
ZITADEL_FIRSTINSTANCE_PATPATH: /current-dir/admin.pat
|
||||
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: admin
|
||||
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME: Automatically Initialized IAM_OWNER
|
||||
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_TYPE: 1
|
||||
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready", "-d", "db_prod" ]
|
||||
test:
|
||||
- CMD
|
||||
- /app/zitadel
|
||||
- ready
|
||||
interval: 10s
|
||||
timeout: 60s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
volumes:
|
||||
- 'data:/var/lib/postgresql/data:rw'
|
||||
|
||||
zitadel-init:
|
||||
restart: 'no'
|
||||
- .:/current-dir:delegated
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 3000:3000
|
||||
networks:
|
||||
- 'storage'
|
||||
image: 'ghcr.io/zitadel/zitadel:v4.0.0-rc.2'
|
||||
command: [ init, --config, /example-zitadel-config.yaml, --config, /example-zitadel-secrets.yaml ]
|
||||
- zitadel
|
||||
depends_on:
|
||||
db:
|
||||
condition: 'service_healthy'
|
||||
volumes:
|
||||
- './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro'
|
||||
- './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro'
|
||||
|
||||
zitadel-setup:
|
||||
restart: 'no'
|
||||
networks:
|
||||
- 'storage'
|
||||
image: 'ghcr.io/zitadel/zitadel:v4.0.0-rc.2'
|
||||
command: [ setup, --config, /current-dir/example-zitadel-config.yaml, --config, /current-dir/example-zitadel-secrets.yaml, --steps, /current-dir/example-zitadel-init-steps.yaml, --masterkey, MasterkeyNeedsToHave32Characters ]
|
||||
depends_on:
|
||||
zitadel-init:
|
||||
condition: 'service_completed_successfully'
|
||||
restart: false
|
||||
volumes:
|
||||
- '.:/current-dir:rw'
|
||||
|
||||
zitadel:
|
||||
restart: 'unless-stopped'
|
||||
networks:
|
||||
- 'backend'
|
||||
- 'storage'
|
||||
labels:
|
||||
- "traefik.http.routers.zitadel.rule=!PathPrefix(`/ui/v2/login`)"
|
||||
- "traefik.http.routers.zitadel.tls=true" # Traefik uses a self-signed certificate
|
||||
- "traefik.http.services.zitadel.loadbalancer.passhostheader=true"
|
||||
- "traefik.http.services.zitadel.loadbalancer.server.scheme=h2c"
|
||||
- "traefik.http.services.zitadel.loadbalancer.server.port=8080"
|
||||
image: 'ghcr.io/zitadel/zitadel:v4.0.0-rc.2'
|
||||
command: [ start, --config, /example-zitadel-config.yaml, --config, /example-zitadel-secrets.yaml, --masterkey, MasterkeyNeedsToHave32Characters ]
|
||||
depends_on:
|
||||
zitadel-setup:
|
||||
condition: 'service_completed_successfully'
|
||||
restart: true
|
||||
volumes:
|
||||
- './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro'
|
||||
- './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro'
|
||||
healthcheck:
|
||||
test: [ "CMD", "/app/zitadel", "ready", "--config", "/example-zitadel-config.yaml", "--config", "/example-zitadel-secrets.yaml" ]
|
||||
interval: 10s
|
||||
timeout: 60s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
condition: service_healthy
|
||||
|
||||
login:
|
||||
restart: 'unless-stopped'
|
||||
labels:
|
||||
- "traefik.http.routers.login.rule=PathPrefix(`/ui/v2/login`)"
|
||||
- "traefik.http.routers.login.tls=true" # Traefik uses a self-signed certificate
|
||||
- "traefik.http.services.login.loadbalancer.passhostheader=true"
|
||||
- "traefik.http.services.login.loadbalancer.server.port=3000"
|
||||
image: 'ghcr.io/zitadel/zitadel-login:v4.0.0-rc.2'
|
||||
restart: unless-stopped
|
||||
image: ghcr.io/zitadel/zitadel-login:latest
|
||||
# If you can't use the network_mode service:zitadel, you can pass the environment variable CUSTOM_REQUEST_HEADERS=Host:localhost instead.
|
||||
network_mode: service:zitadel
|
||||
environment:
|
||||
- ZITADEL_API_URL=http://localhost:8080
|
||||
- NEXT_PUBLIC_BASE_PATH=/ui/v2/login
|
||||
- ZITADEL_SERVICE_USER_TOKEN_FILE=/current-dir/login-client-pat
|
||||
- ZITADEL_SERVICE_USER_TOKEN_FILE=/current-dir/login-client.pat
|
||||
user: "${UID:-1000}"
|
||||
network_mode: service:zitadel
|
||||
volumes:
|
||||
- '.:/current-dir:ro'
|
||||
depends_on:
|
||||
zitadel-setup:
|
||||
condition: 'service_completed_successfully'
|
||||
restart: false
|
||||
|
||||
traefik:
|
||||
image: traefik:latest
|
||||
command: --providers.docker --api.insecure=true --entrypoints.websecure.address=:443 --log.level=DEBUG --accesslog
|
||||
networks:
|
||||
- 'backend'
|
||||
ports:
|
||||
- "443:443"
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- .:/current-dir:ro
|
||||
depends_on:
|
||||
zitadel:
|
||||
condition: 'service_healthy'
|
||||
login:
|
||||
condition: 'service_started'
|
||||
condition: service_healthy
|
||||
restart: false
|
||||
|
||||
db:
|
||||
restart: unless-stopped
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
PGUSER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- pg_isready
|
||||
- -d
|
||||
- zitadel
|
||||
- -U
|
||||
- postgres
|
||||
interval: 10s
|
||||
timeout: 30s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
networks:
|
||||
- zitadel
|
||||
|
||||
networks:
|
||||
storage:
|
||||
backend:
|
||||
|
||||
|
||||
volumes:
|
||||
data:
|
||||
zitadel:
|
||||
|
@@ -1,22 +0,0 @@
|
||||
# All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml
|
||||
|
||||
ExternalSecure: true
|
||||
ExternalPort: 443
|
||||
|
||||
# Traefik terminates TLS. Inside the Docker network, we use plain text.
|
||||
TLS.Enabled: false
|
||||
|
||||
# If not using the docker compose example, adjust these values for connecting ZITADEL to your PostgreSQL
|
||||
Database:
|
||||
postgres:
|
||||
Host: 'db'
|
||||
Port: 5432
|
||||
Database: zitadel
|
||||
User.SSL.Mode: 'disable'
|
||||
Admin.SSL.Mode: 'disable'
|
||||
|
||||
# Access logs allow us to debug Network issues
|
||||
LogStore.Access.Stdout.Enabled: true
|
||||
|
||||
# Skipping the MFA init step allows us to immediately authenticate at the console
|
||||
DefaultInstance.LoginPolicy.MfaInitSkipLifetime: "0s"
|
@@ -1,11 +0,0 @@
|
||||
# All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/setup/steps.yaml
|
||||
FirstInstance:
|
||||
LoginClientPatPath: '/current-dir/login-client-pat'
|
||||
Org:
|
||||
# We want to authenticate immediately at the console without changing the password
|
||||
Human.PasswordChangeRequired: false
|
||||
LoginClient:
|
||||
Machine:
|
||||
Username: 'login-client'
|
||||
Name: 'Automatically Initialized IAM Login Client'
|
||||
Pat.ExpirationDate: '2029-01-01T00:00:00Z'
|
@@ -1,12 +0,0 @@
|
||||
# All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml
|
||||
|
||||
# If not using the docker compose example, adjust these values for connecting ZITADEL to your PostgreSQL
|
||||
Database:
|
||||
postgres:
|
||||
User:
|
||||
# If the user doesn't exist already, it is created
|
||||
Username: 'zitadel_user'
|
||||
Password: 'zitadel'
|
||||
Admin:
|
||||
Username: 'root'
|
||||
Password: 'postgres'
|
47
docs/docs/self-hosting/manage/login-client.mdx
Normal file
47
docs/docs/self-hosting/manage/login-client.mdx
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Connect your Self-Hosted Login UI to Zitadel
|
||||
sidebar_label: Create a Login Client
|
||||
---
|
||||
|
||||
To enable your self-hosted Login UI to connect to the Zitadel API, it needs a token for a user with the IAM_LOGIN_CLIENT role.
|
||||
On new installations, the Zitadel setup job can be configured to automatically write a Personal Access Token (PAT) for the login client.
|
||||
Check out [one of the deployment examples](https://zitadel.com/docs/self-hosting/deploy/overview) to learn how to do this.
|
||||
|
||||
However, if you want to replace the v1 login of an existing installation by a self-hosted v2 login, the setup job won't execute these steps.
|
||||
In that case, you can create a new PAT for the login client manually.
|
||||
|
||||
## Create a Login Client User{#create-login-client}
|
||||
|
||||
In the following URLs, replace the base URL and the user ID according to your environment.
|
||||
|
||||
1. Create a new machine user, for example at http://localhost:8080/ui/console/users/create-machine
|
||||
2. Create a PAT, for example at http://localhost:8080/ui/console/users/332169800719532035?new=true&id=pat
|
||||
3. Save the PAT to a file, for example `/path/on/your/host/login-client.pat`
|
||||
4. Make sure the user has the `Iam Login Client` role (internally called `IAM_LOGIN_CLIENT`), for example at http://localhost:8080/ui/console/instance/members
|
||||
|
||||
# Configure the Login UI
|
||||
|
||||
Make sure your Login UI has the environment variable `ZITADEL_SERVICE_USER_TOKEN` set with your PAT.
|
||||
If you run the Login UI with Docker, you can also mount the file into the container and reference it by passing the environment variable `ZITADEL_SERVICE_USER_TOKEN_FILE`.
|
||||
For example:
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 -v /path/on/your/host/login-client.pat:/path/in/container/login-client.pat:ro -e ZITADEL_SERVICE_USER_TOKEN_FILE=/path/in/container/login-client.pat ghcr.io/zitadel/zitadel-login:latest
|
||||
```
|
||||
|
||||
# Enable the Login UI for all users{#require-login-v2}
|
||||
|
||||
:::caution
|
||||
Before doing this, make sure you have a working PAT for an Iam Owner user.
|
||||
In case something goes wrong and you lock yourself out from the login screen, you can revert the changes.
|
||||
Create a machine user PAT like you created the [login client PAT above](#create-login-client), but give the user the Iam Owner role (internally called `IAM_OWNER`).
|
||||
:::
|
||||
|
||||
Enable the `Login V2` feature flag, for example at the bottom of http://localhost:8080/ui/console/instance?id=features.
|
||||
Enter the base URI of your Login UI, for example `http://localhost:3000/ui/v2/login`.
|
||||
|
||||
# Test
|
||||
|
||||
That's it!
|
||||
Click your users avatar in the top right corner of the console and select `Log in With Another Account`.
|
||||
You should see the new Login UI.
|
@@ -67,6 +67,5 @@
|
||||
"@docusaurus/module-type-aliases": "^3.8.1",
|
||||
"@docusaurus/types": "^3.8.1",
|
||||
"tailwindcss": "^3.2.4"
|
||||
},
|
||||
"packageManager": "pnpm@9.1.2+sha256.19c17528f9ca20bd442e4ca42f00f1b9808a9cb419383cd04ba32ef19322aba7"
|
||||
}
|
||||
}
|
@@ -1094,6 +1094,7 @@ module.exports = {
|
||||
items: [
|
||||
"self-hosting/manage/production",
|
||||
"self-hosting/manage/productionchecklist",
|
||||
"self-hosting/manage/login-client",
|
||||
"self-hosting/manage/configure/configure",
|
||||
{
|
||||
type: "category",
|
||||
|
@@ -17,7 +17,7 @@
|
||||
"clean": "rm -rf .turbo node_modules"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"devDependencies": {
|
||||
"@types/pg": "^8.11.6",
|
||||
"cypress-wait-until": "^3.0.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
@@ -26,9 +26,7 @@
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "^5.5.4",
|
||||
"uuid": "^10.0.0",
|
||||
"wait-on": "^7.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"wait-on": "^7.2.0",
|
||||
"@types/node": "^22.3.0",
|
||||
"cypress": "^14.5.3"
|
||||
}
|
||||
|
12
package.json
12
package.json
@@ -1,15 +1,14 @@
|
||||
{
|
||||
"packageManager": "pnpm@9.1.2+sha256.19c17528f9ca20bd442e4ca42f00f1b9808a9cb419383cd04ba32ef19322aba7",
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"private": true,
|
||||
"name": "zitadel-monorepo",
|
||||
"scripts": {
|
||||
"generate": "turbo run generate",
|
||||
"changeset": "changeset",
|
||||
"devcontainer": "devcontainer",
|
||||
"devcontainer:lint-unit": "pnpm devcontainer up --config .devcontainer/turbo-lint-unit/devcontainer.json --workspace-folder . --remove-existing-container",
|
||||
"devcontainer:integration:login": "pnpm devcontainer up --config .devcontainer/login-integration/devcontainer.json --workspace-folder . --remove-existing-container",
|
||||
"devcontainer:lint-unit": "FAIL_COMMANDS_ON_ERRORS=true devcontainer up --prebuild --config .devcontainer/turbo-lint-unit/devcontainer.json --workspace-folder .",
|
||||
"devcontainer:integration:login": "FAIL_COMMANDS_ON_ERRORS=true devcontainer up --prebuild --config .devcontainer/login-integration/devcontainer.json --workspace-folder .",
|
||||
"clean": "turbo run clean",
|
||||
"clean:all": "pnpm run clean && rm -rf .turbo node_modules",
|
||||
"generate": "turbo run generate"
|
||||
"clean:all": "pnpm run clean && rm -rf .turbo node_modules"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
@@ -21,6 +20,7 @@
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.29.5",
|
||||
"@devcontainers/cli": "^0.80.0",
|
||||
"sass": "^1.64.1",
|
||||
"turbo": "2.5.5"
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"name": "@zitadel/client",
|
||||
"version": "1.3.1",
|
||||
"license": "MIT",
|
||||
|
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"name": "@zitadel/proto",
|
||||
"version": "1.3.1",
|
||||
"license": "MIT",
|
||||
@@ -77,7 +78,7 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"generate": "pnpm exec buf generate ../../proto",
|
||||
"generate": "buf generate ../../proto",
|
||||
"clean": "rm -rf zitadel .turbo node_modules google protoc-gen-openapiv2 validate cjs types es"
|
||||
},
|
||||
"dependencies": {
|
||||
|
2672
pnpm-lock.yaml
generated
2672
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"ui": "tui",
|
||||
"globalDependencies": ["**/.env.*local"],
|
||||
"globalDependencies": [
|
||||
"**/.env.*local"
|
||||
],
|
||||
"globalEnv": [
|
||||
"DEBUG",
|
||||
"VERCEL_URL",
|
||||
@@ -36,6 +38,7 @@
|
||||
},
|
||||
"start": {},
|
||||
"test:unit": {},
|
||||
"test:integration:login": {},
|
||||
"test:acceptance": {},
|
||||
"test:e2e": {},
|
||||
"lint": {},
|
||||
|
Reference in New Issue
Block a user