update main

This commit is contained in:
Elio Bischof
2025-08-05 18:25:29 +02:00
parent 41ca21491c
commit 579f921374
12 changed files with 61 additions and 63 deletions

View File

@@ -3,7 +3,7 @@ services:
devcontainer: devcontainer:
container_name: devcontainer container_name: devcontainer
build: build:
context: ../base context: .
volumes: volumes:
- ../../:/workspaces:cached - ../../:/workspaces:cached
command: sleep infinity command: sleep infinity

View File

@@ -178,4 +178,3 @@ services:
# depends_on: # depends_on:
# configure-login: # configure-login:
# condition: "service_completed_successfully" # condition: "service_completed_successfully"

View File

@@ -13,7 +13,7 @@ on:
outputs: outputs:
login_build_image: login_build_image:
description: 'The full image tag of the standalone login image' description: 'The full image tag of the standalone login image'
value: ${{ jobs.login-container.outputs.login_build_image }} value: ${{ inputs.login_build_image_name }}:${{ github.sha }}
permissions: permissions:
packages: write packages: write
@@ -34,19 +34,6 @@ jobs:
login_build_image: ${{ steps.short-sha.outputs.login_build_image }} login_build_image: ${{ steps.short-sha.outputs.login_build_image }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Get short SHA
id: short-sha
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
# For PRs: Use the HEAD SHA (not the merge commit)
SHORT_SHA=$(echo "${{ github.event.pull_request.head.sha }}" | cut -c1-7)
else
# For pushes: Use the current commit
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
fi
echo "short_sha=$SHORT_SHA" >> $GITHUB_OUTPUT
echo "login_build_image=${{ inputs.login_build_image_name }}:$SHORT_SHA" >> $GITHUB_OUTPUT
echo "Short SHA: $SHORT_SHA"
- name: Login meta - name: Login meta
id: login-meta id: login-meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
@@ -56,7 +43,7 @@ jobs:
annotations: | annotations: |
manifest:org.opencontainers.image.licenses=MIT manifest:org.opencontainers.image.licenses=MIT
tags: | tags: |
type=raw,value=${{ steps.short-sha.outputs.short_sha }} type=sha,prefix=,format=long
- name: Login to Docker registry - name: Login to Docker registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:

View File

@@ -42,7 +42,7 @@ jobs:
run: docker compose --file .devcontainer/login-integration/docker-compose.yaml ps run: docker compose --file .devcontainer/login-integration/docker-compose.yaml ps
- name: Print Config - name: Print Config
if: failure() if: failure()
run: COMPOSE_BAKE=1 docker compose --file .devcontainer/base/docker-compose.yaml --file .devcontainer/login-integration/docker-compose.yaml config login-integration run: COMPOSE_BAKE=1 docker compose --file .devcontainer/login-integration/docker-compose.yaml config login-integration
env: env:
LOGIN_TAG: ${{ inputs.login_build_image }} LOGIN_TAG: ${{ inputs.login_build_image }}
- name: Show Container Logs - name: Show Container Logs

View File

@@ -524,7 +524,7 @@ OIDC:
PollInterval: 5s # ZITADEL_OIDC_DEVICEAUTH_POLLINTERVAL PollInterval: 5s # ZITADEL_OIDC_DEVICEAUTH_POLLINTERVAL
UserCode: UserCode:
CharSet: "BCDFGHJKLMNPQRSTVWXZ" # ZITADEL_OIDC_DEVICEAUTH_USERCODE_CHARSET 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 DashInterval: 4 # ZITADEL_OIDC_DEVICEAUTH_USERCODE_DASHINTERVAL
DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_OIDC_DEFAULTLOGINURLV2 DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_OIDC_DEFAULTLOGINURLV2
DefaultLogoutURLV2: "/ui/v2/login/logout?post_logout_redirect=" # ZITADEL_OIDC_DEFAULTLOGOUTURLV2 DefaultLogoutURLV2: "/ui/v2/login/logout?post_logout_redirect=" # ZITADEL_OIDC_DEFAULTLOGOUTURLV2

View File

@@ -423,6 +423,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
if (allowed) { if (allowed) {
this.oidcForm.enable(); this.oidcForm.enable();
this.oidcForm.controls['clientId'].disable();
this.oidcTokenForm.enable(); this.oidcTokenForm.enable();
this.apiForm.enable(); this.apiForm.enable();
this.samlForm.enable(); this.samlForm.enable();

View File

@@ -1,4 +1,4 @@
import React, { Fragment, useContext, useEffect, useState } from "react"; import { Fragment, useContext, useEffect, useState } from "react";
import { AuthRequestContext } from "../utils/authrequest"; import { AuthRequestContext } from "../utils/authrequest";
import { Listbox } from "@headlessui/react"; import { Listbox } from "@headlessui/react";
import { Transition } from "@headlessui/react"; import { Transition } from "@headlessui/react";
@@ -115,6 +115,14 @@ export function SetAuthRequest() {
}`, }`,
]; ];
const scopeExplanations = new Map([
['urn:zitadel:iam:org:project:id:zitadel:aud', 'Requested projectid will be added to the audience of the access token.'],
['urn:zitadel:iam:user:metadata', 'Metadata of the user will be included in the token. The values are base64 encoded.'],
[`urn:zitadel:iam:org:id:${
organizationId ? organizationId : "[organizationId]"
}`, 'Enforce that the user is a member of the selected organization.']
]);
const [scopeState, setScopeState] = useState( const [scopeState, setScopeState] = useState(
[true, true, true, false, false, false, false, false] [true, true, true, false, false, false, false, false]
// new Array(allScopes.length).fill(false) // new Array(allScopes.length).fill(false)
@@ -161,8 +169,13 @@ export function SetAuthRequest() {
return input; return input;
}; };
useEffect(async () => { useEffect(() => {
setCodeChallenge(await encodeCodeChallenge(codeVerifier)); const updateCodeChallange = async () => {
const newCodeChallange = await encodeCodeChallenge(codeVerifier)
setCodeChallenge(newCodeChallange);
}
updateCodeChallange();
}, [codeVerifier]); }, [codeVerifier]);
useEffect(() => { useEffect(() => {
@@ -559,6 +572,7 @@ export function SetAuthRequest() {
name="scopes" name="scopes"
value={`${scope}`} value={`${scope}`}
checked={scopeState[scopeIndex]} checked={scopeState[scopeIndex]}
disabled={scope === 'openid'}
onChange={() => { onChange={() => {
toggleScope(scopeIndex); toggleScope(scopeIndex);
}} }}
@@ -571,6 +585,11 @@ export function SetAuthRequest() {
</strong> </strong>
) : null} ) : null}
</label> </label>
{scopeExplanations.has(scope) && (
<span className={clsx(hintClasses, 'ml-1')}>
{scopeExplanations.get(scope)}
</span>
)}
</div> </div>
); );
})} })}

View File

@@ -4,7 +4,6 @@ import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import Layout from "@theme/Layout"; import Layout from "@theme/Layout";
import ThemedImage from "@theme/ThemedImage"; import ThemedImage from "@theme/ThemedImage";
import clsx from "clsx"; import clsx from "clsx";
import React from "react";
import Column from "../components/column"; import Column from "../components/column";
import { import {

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useEffect, useState } from "react";
export const AuthRequestContext = React.createContext(null); export const AuthRequestContext = React.createContext(null);
@@ -34,7 +34,7 @@ export default ({ children }) => {
const id_token_hint = params.get("id_token_hint"); const id_token_hint = params.get("id_token_hint");
const organization_id = params.get("organization_id"); const organization_id = params.get("organization_id");
setInstance(instance_param ?? "https://mydomain-xyza.zitadel.cloud/"); setInstance(instance_param ?? "http://localhost:8080/");
setClientId(client_id ?? "170086824411201793@yourapp"); setClientId(client_id ?? "170086824411201793@yourapp");
setRedirectUri( setRedirectUri(
redirect_uri ?? "http://localhost:8080/api/auth/callback/zitadel" redirect_uri ?? "http://localhost:8080/api/auth/callback/zitadel"

View File

@@ -7,6 +7,7 @@ import (
http_util "github.com/zitadel/zitadel/internal/api/http" http_util "github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/api/ui/console" "github.com/zitadel/zitadel/internal/api/ui/console"
"github.com/zitadel/zitadel/internal/api/ui/login" "github.com/zitadel/zitadel/internal/api/ui/login"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2" "github.com/zitadel/zitadel/internal/eventstore/handler/v2"
@@ -417,12 +418,14 @@ func (u *userNotifier) reduceSessionOTPSMSChallenged(event eventstore.Event) (*h
if alreadyHandled { if alreadyHandled {
return nil return nil
} }
s, err := u.queries.SessionByID(ctx, true, e.Aggregate().ID, "", nil)
ctx, err = u.queries.Origin(ctx, e)
if err != nil { if err != nil {
return err return err
} }
ctx, err = u.queries.Origin(ctx, e) sessionWriteModel := command.NewSessionWriteModel(e.Aggregate().ID, e.Aggregate().InstanceID)
err = u.queries.es.FilterToQueryReducer(ctx, sessionWriteModel)
if err != nil { if err != nil {
return err return err
} }
@@ -432,8 +435,8 @@ func (u *userNotifier) reduceSessionOTPSMSChallenged(event eventstore.Event) (*h
return u.queue.Insert(ctx, return u.queue.Insert(ctx,
&notification.Request{ &notification.Request{
Aggregate: e.Aggregate(), Aggregate: e.Aggregate(),
UserID: s.UserFactor.UserID, UserID: sessionWriteModel.UserID,
UserResourceOwner: s.UserFactor.ResourceOwner, UserResourceOwner: sessionWriteModel.UserResourceOwner,
TriggeredAtOrigin: http_util.DomainContext(ctx).Origin(), TriggeredAtOrigin: http_util.DomainContext(ctx).Origin(),
EventType: e.EventType, EventType: e.EventType,
NotificationType: domain.NotificationTypeSms, NotificationType: domain.NotificationTypeSms,

View File

@@ -1349,19 +1349,12 @@ func Test_userNotifier_reduceOTPSMSChallenged(t *testing.T) {
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, queue *mock.MockQueue) (f fields, a args, w want) { test: func(ctrl *gomock.Controller, queries *mock.MockQueries, queue *mock.MockQueue) (f fields, a args, w want) {
testCode := "testcode" testCode := "testcode"
_, code := cryptoValue(t, ctrl, testCode) _, code := cryptoValue(t, ctrl, testCode)
queries.EXPECT().SessionByID(gomock.Any(), gomock.Any(), sessionID, gomock.Any(), nil).Return(&query.Session{
ID: sessionID,
ResourceOwner: instanceID,
UserFactor: query.SessionUserFactor{
UserID: userID,
ResourceOwner: orgID,
},
}, nil)
queue.EXPECT().Insert( queue.EXPECT().Insert(
gomock.Any(), gomock.Any(),
&notification.Request{ &notification.Request{
UserID: userID, UserID: "", // Empty since no session events are provided
UserResourceOwner: orgID, UserResourceOwner: "", // Empty since no session events are provided
TriggeredAtOrigin: eventOrigin, TriggeredAtOrigin: eventOrigin,
URLTemplate: "", URLTemplate: "",
Code: code, Code: code,
@@ -1387,11 +1380,15 @@ func Test_userNotifier_reduceOTPSMSChallenged(t *testing.T) {
gomock.Any(), gomock.Any(),
gomock.Any(), gomock.Any(),
).Return(nil) ).Return(nil)
mockQuerier := es_repo_mock.NewMockQuerier(ctrl)
mockQuerier.EXPECT().FilterToReducer(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
return fields{ return fields{
queries: queries, queries: queries,
queue: queue, queue: queue,
es: eventstore.NewEventstore(&eventstore.Config{ es: eventstore.NewEventstore(&eventstore.Config{
Querier: es_repo_mock.NewRepo(t).ExpectFilterEvents().MockQuerier, Querier: mockQuerier,
}), }),
}, args{ }, args{
event: &session.OTPSMSChallengedEvent{ event: &session.OTPSMSChallengedEvent{
@@ -1421,19 +1418,12 @@ func Test_userNotifier_reduceOTPSMSChallenged(t *testing.T) {
IsPrimary: true, IsPrimary: true,
}}, }},
}, nil) }, nil)
queries.EXPECT().SessionByID(gomock.Any(), gomock.Any(), sessionID, gomock.Any(), nil).Return(&query.Session{
ID: sessionID,
ResourceOwner: instanceID,
UserFactor: query.SessionUserFactor{
UserID: userID,
ResourceOwner: orgID,
},
}, nil)
queue.EXPECT().Insert( queue.EXPECT().Insert(
gomock.Any(), gomock.Any(),
&notification.Request{ &notification.Request{
UserID: userID, UserID: "", // Empty since no session events are provided
UserResourceOwner: orgID, UserResourceOwner: "", // Empty since no session events are provided
TriggeredAtOrigin: fmt.Sprintf("%s://%s:%d", externalProtocol, instancePrimaryDomain, externalPort), TriggeredAtOrigin: fmt.Sprintf("%s://%s:%d", externalProtocol, instancePrimaryDomain, externalPort),
URLTemplate: "", URLTemplate: "",
Code: code, Code: code,
@@ -1459,11 +1449,15 @@ func Test_userNotifier_reduceOTPSMSChallenged(t *testing.T) {
gomock.Any(), gomock.Any(),
gomock.Any(), gomock.Any(),
).Return(nil) ).Return(nil)
mockQuerier := es_repo_mock.NewMockQuerier(ctrl)
mockQuerier.EXPECT().FilterToReducer(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
return fields{ return fields{
queries: queries, queries: queries,
queue: queue, queue: queue,
es: eventstore.NewEventstore(&eventstore.Config{ es: eventstore.NewEventstore(&eventstore.Config{
Querier: es_repo_mock.NewRepo(t).ExpectFilterEvents().MockQuerier, Querier: mockQuerier,
}), }),
}, args{ }, args{
event: &session.OTPSMSChallengedEvent{ event: &session.OTPSMSChallengedEvent{
@@ -1484,19 +1478,11 @@ func Test_userNotifier_reduceOTPSMSChallenged(t *testing.T) {
{ {
name: "external code", name: "external code",
test: func(ctrl *gomock.Controller, queries *mock.MockQueries, queue *mock.MockQueue) (f fields, a args, w want) { test: func(ctrl *gomock.Controller, queries *mock.MockQueries, queue *mock.MockQueue) (f fields, a args, w want) {
queries.EXPECT().SessionByID(gomock.Any(), gomock.Any(), sessionID, gomock.Any(), nil).Return(&query.Session{
ID: sessionID,
ResourceOwner: instanceID,
UserFactor: query.SessionUserFactor{
UserID: userID,
ResourceOwner: orgID,
},
}, nil)
queue.EXPECT().Insert( queue.EXPECT().Insert(
gomock.Any(), gomock.Any(),
&notification.Request{ &notification.Request{
UserID: userID, UserID: "", // Empty since no session events are provided
UserResourceOwner: orgID, UserResourceOwner: "", // Empty since no session events are provided
TriggeredAtOrigin: eventOrigin, TriggeredAtOrigin: eventOrigin,
URLTemplate: "", URLTemplate: "",
Code: nil, Code: nil,
@@ -1522,11 +1508,15 @@ func Test_userNotifier_reduceOTPSMSChallenged(t *testing.T) {
gomock.Any(), gomock.Any(),
gomock.Any(), gomock.Any(),
).Return(nil) ).Return(nil)
mockQuerier := es_repo_mock.NewMockQuerier(ctrl)
mockQuerier.EXPECT().FilterToReducer(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
return fields{ return fields{
queries: queries, queries: queries,
queue: queue, queue: queue,
es: eventstore.NewEventstore(&eventstore.Config{ es: eventstore.NewEventstore(&eventstore.Config{
Querier: es_repo_mock.NewRepo(t).ExpectFilterEvents().MockQuerier, Querier: mockQuerier,
}), }),
}, args{ }, args{
event: &session.OTPSMSChallengedEvent{ event: &session.OTPSMSChallengedEvent{