mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 15:17:33 +00:00
update main
This commit is contained in:
@@ -16,4 +16,4 @@ RUN apt-get update && \
|
|||||||
|
|
||||||
COPY --chown=node:node commands /commands
|
COPY --chown=node:node commands /commands
|
||||||
|
|
||||||
USER node
|
USER node
|
||||||
|
@@ -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
|
||||||
|
@@ -178,4 +178,3 @@ services:
|
|||||||
# depends_on:
|
# depends_on:
|
||||||
# configure-login:
|
# configure-login:
|
||||||
# condition: "service_completed_successfully"
|
# condition: "service_completed_successfully"
|
||||||
|
|
||||||
|
17
.github/workflows/login-container.yml
vendored
17
.github/workflows/login-container.yml
vendored
@@ -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:
|
||||||
|
2
.github/workflows/login-integration-test.yml
vendored
2
.github/workflows/login-integration-test.yml
vendored
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
|
@@ -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>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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"
|
||||||
|
@@ -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,
|
||||||
¬ification.Request{
|
¬ification.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,
|
||||||
|
@@ -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(),
|
||||||
¬ification.Request{
|
¬ification.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(),
|
||||||
¬ification.Request{
|
¬ification.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(),
|
||||||
¬ification.Request{
|
¬ification.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{
|
||||||
|
Reference in New Issue
Block a user