diff --git a/.dockerignore b/.dockerignore index f9db036d2b..b328b97284 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,2 @@ -* -!docker \ No newline at end of file +/* +!/docker diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bad19343d3..db4d5aa5c8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,13 +58,14 @@ jobs: run: pnpm install - name: Build for Docker - run: NEXT_PUBLIC_BASE_PATH=/new-login pnpm build:docker + run: NEXT_PUBLIC_BASE_PATH=/ui/v2/login pnpm build:docker - name: Build and Push Image id: build uses: docker/build-push-action@v5 timeout-minutes: 10 with: + context: . cache-from: type=gha cache-to: type=gha,mode=max tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cd411e1592..79a455b016 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -66,17 +66,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20.x - cache: 'pnpm' - - - name: Setup Cypress binary cache - uses: actions/cache@v4 - with: - path: ~/.cache/Cypress - key: ${{ runner.os }}-cypress-binary-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-cypress-binary- - # The Cypress binary cache needs to be updated together with the pnpm dependencies cache. - # That's why we don't conditionally cache it using if: ${{ matrix.command == 'test:integration' }} - name: Install Dependencies run: pnpm install --frozen-lockfile diff --git a/README.md b/README.md index 6ccfd678b6..67aef1f959 100644 --- a/README.md +++ b/README.md @@ -203,13 +203,11 @@ Go to your instance and create a service user for the login application. The login application creates users on your primary organization and reads policy data. For the sake of simplicity, just make the service user an instance member with the role `IAM_OWNER`. Create a PAT and copy it to the file `apps/login/.env.local` using the key `ZITADEL_SERVICE_USER_TOKEN`. -Also add the users ID to the file using the key `ZITADEL_SERVICE_USER_ID`. The file should look similar to this: ``` ZITADEL_API_URL=https://zitadel-tlx3du.us1.zitadel.cloud -ZITADEL_SERVICE_USER_ID=289106423158521850 ZITADEL_SERVICE_USER_TOKEN=1S6w48thfWFI2klgfwkCnhXJLf9FQ457E-_3H74ePQxfO3Af0Tm4V5Xi-ji7urIl_xbn-Rk ``` @@ -253,9 +251,8 @@ pnpm test:acceptance ### Deploy to Vercel To deploy your own version on Vercel, navigate to your instance and create a service user. -Copy its id from the overview and set it as ZITADEL_SERVICE_USER_ID. Then create a personal access token (PAT), copy and set it as ZITADEL_SERVICE_USER_TOKEN, then navigate to your instance settings and make sure it gets IAM_OWNER permissions. Finally set your instance url as ZITADEL_API_URL. Make sure to set it without trailing slash. -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fzitadel%2Ftypescript&env=ZITADEL_API_URL,ZITADEL_SERVICE_USER_ID,ZITADEL_SERVICE_USER_TOKEN&root-directory=apps/login&envDescription=Setup%20a%20service%20account%20with%20IAM_OWNER%20membership%20on%20your%20instance%20and%20provide%20its%20id%20and%20personal%20access%20token.&project-name=zitadel-login&repository-name=zitadel-login) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fzitadel%2Ftypescript&env=ZITADEL_API_URL,ZITADEL_SERVICE_USER_TOKEN&root-directory=apps/login&envDescription=Setup%20a%20service%20account%20with%20IAM_LOGIN_CLIENT%20membership%20on%20your%20instance%20and%20provide%20its%20personal%20access%20token.&project-name=zitadel-login&repository-name=zitadel-login) diff --git a/acceptance/setup.sh b/acceptance/setup.sh index 596c985d78..8438685dde 100755 --- a/acceptance/setup.sh +++ b/acceptance/setup.sh @@ -17,16 +17,6 @@ if [ -z "${PAT}" ]; then PAT=$(cat ${PAT_FILE}) fi -if [ -z "${ZITADEL_SERVICE_USER_ID}" ]; then - echo "Reading ZITADEL_SERVICE_USER_ID from userinfo endpoint" - USERINFO_RESPONSE=$(curl -s --request POST \ - --url "${ZITADEL_API_INTERNAL_URL}/oidc/v1/userinfo" \ - --header "Authorization: Bearer ${PAT}" \ - --header "Host: ${ZITADEL_API_DOMAIN}") - echo "Received userinfo response: ${USERINFO_RESPONSE}" - ZITADEL_SERVICE_USER_ID=$(echo "${USERINFO_RESPONSE}" | jq --raw-output '.sub') -fi - ################################################################# # Environment files ################################################################# @@ -37,7 +27,6 @@ WRITE_TEST_ENVIRONMENT_FILE=${WRITE_TEST_ENVIRONMENT_FILE:-$(dirname "$0")/../ac echo "Writing environment file to ${WRITE_TEST_ENVIRONMENT_FILE} when done." echo "ZITADEL_API_URL=${ZITADEL_API_URL} -ZITADEL_SERVICE_USER_ID=${ZITADEL_SERVICE_USER_ID} ZITADEL_SERVICE_USER_TOKEN=${PAT} SINK_NOTIFICATION_URL=${SINK_NOTIFICATION_URL} EMAIL_VERIFICATION=true diff --git a/apps/login/.env.integration b/apps/login/.env.integration index 705d7d0733..a72ccdecd2 100644 --- a/apps/login/.env.integration +++ b/apps/login/.env.integration @@ -1,5 +1,4 @@ ZITADEL_API_URL=http://localhost:22222 -ZITADEL_SERVICE_USER_ID="yolo" ZITADEL_SERVICE_USER_TOKEN="yolo" EMAIL_VERIFICATION=true DEBUG=true diff --git a/apps/login/next-env-vars.d.ts b/apps/login/next-env-vars.d.ts index 112eea393f..691bfa6f56 100644 --- a/apps/login/next-env-vars.d.ts +++ b/apps/login/next-env-vars.d.ts @@ -10,24 +10,12 @@ declare namespace NodeJS { SYSTEM_USER_PRIVATE_KEY: string; // The fallback service user private key /** - * Self hosting: The Zitadel API url + * The Zitadel API url */ ZITADEL_API_URL: string; /** - * Takes effect only if ZITADEL_API_URL is not empty. - * This is only relevant if Zitadels runtime has the ZITADEL_INSTANCEHOSTHEADERS config changed. - * The default is x-zitadel-instance-host. - * Most users don't need to set this variable. - */ - ZITADEL_INSTANCE_HOST_HEADER: string; - - /** - * Self hosting: The service user id - */ - ZITADEL_SERVICE_USER_ID: string; - /** - * Self hosting: The service user token + * The service user token */ ZITADEL_SERVICE_USER_TOKEN: string; @@ -35,5 +23,11 @@ declare namespace NodeJS { * Optional: wheter a user must have verified email */ EMAIL_VERIFICATION: string; + + /** + * Optional: custom request headers to be added to every request + * Split by comma, key value pairs separated by colon + */ + CUSTOM_REQUEST_HEADERS: string; } } diff --git a/apps/login/src/lib/service.ts b/apps/login/src/lib/service.ts index 0e83b5ae58..b6d320c0f4 100644 --- a/apps/login/src/lib/service.ts +++ b/apps/login/src/lib/service.ts @@ -44,26 +44,23 @@ export async function createServiceForHost( throw new Error("No token found"); } - const instanceHost = new URL(serviceUrl).host; const transport = createServerTransport(token, { - baseUrl: process.env.ZITADEL_API_URL ?? serviceUrl, - interceptors: - (process.env.ZITADEL_API_URL && - process.env.ZITADEL_API_URL != serviceUrl) || - process.env.ZITADEL_INSTANCE_HOST_HEADER - ? [ - (next) => { - return (req) => { - req.header.set( - process.env.ZITADEL_INSTANCE_HOST_HEADER ?? - "x-zitadel-instance-host", - instanceHost, - ); - return next(req); - }; - }, - ] - : undefined, + baseUrl: serviceUrl, + interceptors: !process.env.CUSTOM_REQUEST_HEADERS + ? undefined + : [ + (next) => { + return (req) => { + process.env.CUSTOM_REQUEST_HEADERS.split(",").forEach( + (header) => { + const kv = header.split(":"); + req.header.set(kv[0], kv[1]); + }, + ); + return next(req); + }; + }, + ], }); return createClientFor(service)(transport); diff --git a/apps/login/src/middleware.ts b/apps/login/src/middleware.ts index e8dda55a26..fec0433917 100644 --- a/apps/login/src/middleware.ts +++ b/apps/login/src/middleware.ts @@ -13,11 +13,7 @@ export const config = { export async function middleware(request: NextRequest) { // escape proxy if the environment is setup for multitenancy - if ( - !process.env.ZITADEL_API_URL || - !process.env.ZITADEL_SERVICE_USER_ID || - !process.env.ZITADEL_SERVICE_USER_TOKEN - ) { + if (!process.env.ZITADEL_API_URL || !process.env.ZITADEL_SERVICE_USER_TOKEN) { return NextResponse.next(); } @@ -28,10 +24,6 @@ export async function middleware(request: NextRequest) { const instanceHost = `${serviceUrl}`.replace("https://", ""); const requestHeaders = new Headers(request.headers); - requestHeaders.set( - "x-zitadel-login-client", - process.env.ZITADEL_SERVICE_USER_ID, - ); // this is a workaround for the next.js server not forwarding the host header // requestHeaders.set("x-zitadel-forwarded", `host="${request.nextUrl.host}"`); diff --git a/package.json b/package.json index d6790adb60..a824e47571 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "generate": "turbo run generate", "build": "turbo run build", - "build:docker": "rm -rf ./out ./docker && mkdir -p ./docker && turbo run build --filter=./packages/zitadel-client && turbo prune @zitadel/login --docker && cd ./docker && cp -r ../out/json/* . && pnpm install --frozen-lockfile && cp -r ../out/full/* . && turbo run build:standalone && cd ..", + "build:docker": "rm -rf ./out ./docker && turbo run build --filter=./packages/zitadel-client && turbo prune @zitadel/login --docker && mkdir -p ./docker && cd ./docker && cp -r ../out/json/* . && pnpm install --frozen-lockfile && cp -r ../out/full/* . && turbo run build:standalone && cd ..", "build:packages": "turbo run build --filter=./packages/*", "build:apps": "turbo run build --filter=./apps/*", "test": "turbo run test", diff --git a/turbo.json b/turbo.json index 61316b800e..c8d8b18af3 100644 --- a/turbo.json +++ b/turbo.json @@ -10,10 +10,9 @@ "SYSTEM_USER_ID", "SYSTEM_USER_PRIVATE_KEY", "ZITADEL_API_URL", - "ZITADEL_SERVICE_USER_ID", "ZITADEL_SERVICE_USER_TOKEN", "NEXT_PUBLIC_BASE_PATH", - "ZITADEL_INSTANCE_HOST_HEADER" + "CUSTOM_REQUEST_HEADERS" ], "tasks": { "generate": {