Files
zitadel/internal/command/instance_features.go
T
Livio SpringandGitHub ce30a5a98e feat(oidc): move back-channel logout from beta to GA (#11493)
# Which Problems Are Solved

This PR marks the OIDC Back-Channel Logout as general available (GA).

# How the Problems Are Solved

- API:
- deprecated the feature toggle (to prevent breaking changes) in v2beta
and v2 API
  - removed all related event logic and updated the projection iteration
  - removed the toggle usage for back-channel logout
  - removed related translations
- Management Console:
  - removed the feature toggle and its translations
- Docs:
  - removed all beta labels and feature toggle notes

# Additional Changes

none

# Additional Context

- closes #11277 
- requires backport to v4.x
2026-02-05 10:51:09 +00:00

89 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
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 *InstanceSetupFeatures) preparation.Validation {
return func() (preparation.CreateCommands, error) {
features, err := f.ToInstanceFeatures()
if err != nil {
return nil, err
}
return func(ctx context.Context, _ preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
wm := NewInstanceFeaturesWriteModel(instanceID)
return wm.setCommands(ctx, features), 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
}