Files
zitadel/internal/command/instance_features.go
21b28b56ac fix: revert feature key for configs back to ConsoleUseV2UserApi (#11928)
# Which Problems Are Solved

https://github.com/zitadel/zitadel/pull/11390 renamed "Console" to
"Management Console". While
https://github.com/zitadel/zitadel/pull/11706 already reverted an
unintended rename of the feature key to enable the management console to
use the V2 API for user creation. It was now also discovered that the
rename of the feature itself also broke existing (default)
configurations.

# How the Problems Are Solved

Added a `mapstructure` tag on the instance feature to handle existing
configs.

# Additional Changes

Removed unused `TokenExchange` from the default configuration.

# Additional Context

- relates to #11390 
- relates to #11706
- requires backport to v4.x

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Marco A. <marco@zitadel.com>
2026-03-30 15:59:57 +00:00

84 lines
2.9 KiB
Go

package command
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/command/preparation"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/feature"
"github.com/zitadel/zitadel/internal/repository/feature/feature_v2"
"github.com/zitadel/zitadel/internal/zerrors"
)
type InstanceFeatures struct {
LoginDefaultOrg *bool
UserSchema *bool
ImprovedPerformance []feature.ImprovedPerformanceType
DebugOIDCParentError *bool
OIDCSingleV1SessionTermination *bool
LoginV2 *feature.LoginV2
PermissionCheckV2 *bool
ManagementConsoleUseV2UserApi *bool `mapstructure:"ConsoleUseV2UserApi"` // for backwards compatibility we need to change this back to the old config name
EnableRelationalTables *bool
}
func (m *InstanceFeatures) isEmpty() bool {
return m == nil || (m.LoginDefaultOrg == nil &&
m.UserSchema == nil &&
// nil check to allow unset improvements
m.ImprovedPerformance == nil &&
m.DebugOIDCParentError == nil &&
m.OIDCSingleV1SessionTermination == nil &&
m.LoginV2 == nil &&
m.PermissionCheckV2 == nil &&
m.ManagementConsoleUseV2UserApi == nil &&
m.EnableRelationalTables == nil)
}
func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures) (*domain.ObjectDetails, error) {
if f.isEmpty() {
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-Vigh1", "Errors.NoChangesFound")
}
wm := NewInstanceFeaturesWriteModel(authz.GetInstance(ctx).InstanceID())
if err := c.eventstore.FilterToQueryReducer(ctx, wm); err != nil {
return nil, err
}
commands := wm.setCommands(ctx, f)
if len(commands) == 0 {
return writeModelToObjectDetails(wm.WriteModel), nil
}
events, err := c.eventstore.Push(ctx, commands...)
if err != nil {
return nil, err
}
return pushedEventsToObjectDetails(events), nil
}
func prepareSetFeatures(instanceID string, f *InstanceFeatures) preparation.Validation {
return func() (preparation.CreateCommands, error) {
return func(ctx context.Context, _ preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
wm := NewInstanceFeaturesWriteModel(instanceID)
return wm.setCommands(ctx, f), nil
}, nil
}
}
func (c *Commands) ResetInstanceFeatures(ctx context.Context) (*domain.ObjectDetails, error) {
instanceID := authz.GetInstance(ctx).InstanceID()
wm := NewInstanceFeaturesWriteModel(instanceID)
if err := c.eventstore.FilterToQueryReducer(ctx, wm); err != nil {
return nil, err
}
if wm.isEmpty() {
return writeModelToObjectDetails(wm.WriteModel), nil
}
aggregate := feature_v2.NewAggregate(instanceID, instanceID)
events, err := c.eventstore.Push(ctx, feature_v2.NewResetEvent(ctx, aggregate, feature_v2.InstanceResetEventType))
if err != nil {
return nil, err
}
return pushedEventsToObjectDetails(events), nil
}