mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 06:07:33 +00:00
fix: Custom text split features (#2225)
* fix: separate tier of custom text (message and login) * fix: add migration * fix: build problems * fix: tests * Update internal/api/grpc/admin/features.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/api/grpc/admin/features.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix: rename sql file * fix: change sql files * fix: console * fix: console Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
@@ -36,23 +36,23 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<cnsl-info-section class="warn"
|
<cnsl-info-section class="warn"
|
||||||
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false"
|
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.login'] | hasFeature | async) == false"
|
||||||
type="WARN">
|
type="WARN">
|
||||||
{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
||||||
'custom_text'})}}
|
'custom_text.login'})}}
|
||||||
</cnsl-info-section>
|
</cnsl-info-section>
|
||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
|
||||||
<div class="content" >
|
<div class="content" >
|
||||||
<cnsl-edit-text label="one" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false" [default$]="getDefaultInitMessageTextMap$" [current$]="getCustomInitMessageTextMap$" (changedValues)="updateCurrentValues(
|
<cnsl-edit-text label="one" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.login'] | hasFeature | async) == false" [default$]="getDefaultInitMessageTextMap$" [current$]="getCustomInitMessageTextMap$" (changedValues)="updateCurrentValues(
|
||||||
$event)"></cnsl-edit-text>
|
$event)"></cnsl-edit-text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="reset-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false" (click)="resetDefault()" color="warn" type="submit"
|
<button class="reset-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.login'] | hasFeature | async) == false" (click)="resetDefault()" color="warn" type="submit"
|
||||||
mat-stroked-button><i class="las la-history"></i> {{ 'ACTIONS.RESETDEFAULT' | translate }}</button>
|
mat-stroked-button><i class="las la-history"></i> {{ 'ACTIONS.RESETDEFAULT' | translate }}</button>
|
||||||
<button class="save-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false" (click)="saveCurrentMessage()" color="primary" type="submit"
|
<button class="save-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.login'] | hasFeature | async) == false" (click)="saveCurrentMessage()" color="primary" type="submit"
|
||||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -20,21 +20,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<cnsl-info-section class="warn"
|
<cnsl-info-section class="warn"
|
||||||
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false"
|
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.message'] | hasFeature | async) == false"
|
||||||
type="WARN">
|
type="WARN">
|
||||||
{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
||||||
'custom_text'})}}
|
'custom_text.message'})}}
|
||||||
</cnsl-info-section>
|
</cnsl-info-section>
|
||||||
|
|
||||||
<div class="content" >
|
<div class="content" >
|
||||||
<cnsl-edit-text [chips]="chips[currentType]" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false" label="one" [default$]="getDefaultInitMessageTextMap$" [current$]="getCustomInitMessageTextMap$" (changedValues)="updateCurrentValues(
|
<cnsl-edit-text [chips]="chips[currentType]" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.message'] | hasFeature | async) == false" label="one" [default$]="getDefaultInitMessageTextMap$" [current$]="getCustomInitMessageTextMap$" (changedValues)="updateCurrentValues(
|
||||||
$event)"></cnsl-edit-text>
|
$event)"></cnsl-edit-text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="reset-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false" (click)="resetDefault()" color="warn" type="submit"
|
<button class="reset-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['custom_text.message'] | hasFeature | async) == false" (click)="resetDefault()" color="warn" type="submit"
|
||||||
mat-stroked-button><i class="las la-history"></i> {{ 'ACTIONS.RESETDEFAULT' | translate }}</button>
|
mat-stroked-button><i class="las la-history"></i> {{ 'ACTIONS.RESETDEFAULT' | translate }}</button>
|
||||||
<button class="save-button" [disabled]="!updateRequest || serviceType == PolicyComponentServiceType.MGMT && (['custom_text'] | hasFeature | async) == false" (click)="saveCurrentMessage()" color="primary" type="submit"
|
<button class="save-button" [disabled]="!updateRequest || serviceType == PolicyComponentServiceType.MGMT && (['custom_text.message'] | hasFeature | async) == false" (click)="saveCurrentMessage()" color="primary" type="submit"
|
||||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -660,7 +660,7 @@
|
|||||||
"2": "Annuliert",
|
"2": "Annuliert",
|
||||||
"3": "Durch IAM Owner gesetzt"
|
"3": "Durch IAM Owner gesetzt"
|
||||||
},
|
},
|
||||||
"NOTAVAILABLE": "Feature {{value}} ist auf Ihrer organisation nicht freigeschaltet!",
|
"NOTAVAILABLE": "Feature {{value}} ist auf Ihrer Organisation nicht freigeschaltet!",
|
||||||
"RETENTIONDAYS": "Tage"
|
"RETENTIONDAYS": "Tage"
|
||||||
},
|
},
|
||||||
"POLICY": {
|
"POLICY": {
|
||||||
|
@@ -2505,6 +2505,8 @@ This is an empty request
|
|||||||
| custom_text | bool | - | |
|
| custom_text | bool | - | |
|
||||||
| privacy_policy | bool | - | |
|
| privacy_policy | bool | - | |
|
||||||
| metadata_user | bool | - | |
|
| metadata_user | bool | - | |
|
||||||
|
| custom_text_message | bool | - | |
|
||||||
|
| custom_text_login | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2691,6 +2693,8 @@ This is an empty request
|
|||||||
| custom_text | bool | - | |
|
| custom_text | bool | - | |
|
||||||
| privacy_policy | bool | - | |
|
| privacy_policy | bool | - | |
|
||||||
| metadata_user | bool | - | |
|
| metadata_user | bool | - | |
|
||||||
|
| custom_text_message | bool | - | |
|
||||||
|
| custom_text_login | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -74,9 +74,10 @@ func setDefaultFeaturesRequestToDomain(req *admin_pb.SetDefaultFeaturesRequest)
|
|||||||
LabelPolicyPrivateLabel: req.LabelPolicy || req.LabelPolicyPrivateLabel,
|
LabelPolicyPrivateLabel: req.LabelPolicy || req.LabelPolicyPrivateLabel,
|
||||||
LabelPolicyWatermark: req.LabelPolicyWatermark,
|
LabelPolicyWatermark: req.LabelPolicyWatermark,
|
||||||
CustomDomain: req.CustomDomain,
|
CustomDomain: req.CustomDomain,
|
||||||
CustomText: req.CustomText,
|
|
||||||
PrivacyPolicy: req.PrivacyPolicy,
|
PrivacyPolicy: req.PrivacyPolicy,
|
||||||
MetadataUser: req.MetadataUser,
|
MetadataUser: req.MetadataUser,
|
||||||
|
CustomTextLogin: req.CustomTextLogin || req.CustomText,
|
||||||
|
CustomTextMessage: req.CustomTextMessage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +98,9 @@ func setOrgFeaturesRequestToDomain(req *admin_pb.SetOrgFeaturesRequest) *domain.
|
|||||||
LabelPolicyPrivateLabel: req.LabelPolicy || req.LabelPolicyPrivateLabel,
|
LabelPolicyPrivateLabel: req.LabelPolicy || req.LabelPolicyPrivateLabel,
|
||||||
LabelPolicyWatermark: req.LabelPolicyWatermark,
|
LabelPolicyWatermark: req.LabelPolicyWatermark,
|
||||||
CustomDomain: req.CustomDomain,
|
CustomDomain: req.CustomDomain,
|
||||||
CustomText: req.CustomText,
|
|
||||||
PrivacyPolicy: req.PrivacyPolicy,
|
PrivacyPolicy: req.PrivacyPolicy,
|
||||||
MetadataUser: req.MetadataUser,
|
MetadataUser: req.MetadataUser,
|
||||||
|
CustomTextLogin: req.CustomTextLogin || req.CustomText,
|
||||||
|
CustomTextMessage: req.CustomTextMessage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,8 +27,10 @@ func FeaturesFromModel(features *features_model.FeaturesView) *features_pb.Featu
|
|||||||
CustomDomain: features.CustomDomain,
|
CustomDomain: features.CustomDomain,
|
||||||
LabelPolicyPrivateLabel: features.LabelPolicyPrivateLabel,
|
LabelPolicyPrivateLabel: features.LabelPolicyPrivateLabel,
|
||||||
LabelPolicyWatermark: features.LabelPolicyWatermark,
|
LabelPolicyWatermark: features.LabelPolicyWatermark,
|
||||||
CustomText: features.CustomText,
|
|
||||||
PrivacyPolicy: features.PrivacyPolicy,
|
PrivacyPolicy: features.PrivacyPolicy,
|
||||||
|
CustomText: features.CustomTextMessage,
|
||||||
|
CustomTextMessage: features.CustomTextMessage,
|
||||||
|
CustomTextLogin: features.CustomTextLogin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -151,8 +151,14 @@ func checkFeatures(features *features_view_model.FeaturesView, requiredFeatures
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if requiredFeature == domain.FeatureCustomText {
|
if requiredFeature == domain.FeatureCustomTextMessage {
|
||||||
if !features.CustomText {
|
if !features.CustomTextMessage {
|
||||||
|
return MissingFeatureErr(requiredFeature)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if requiredFeature == domain.FeatureCustomTextLogin {
|
||||||
|
if !features.CustomTextLogin {
|
||||||
return MissingFeatureErr(requiredFeature)
|
return MissingFeatureErr(requiredFeature)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
@@ -10,6 +10,25 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/policy"
|
"github.com/caos/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CustomLoginTextsReadModel struct {
|
||||||
|
eventstore.WriteModel
|
||||||
|
CustomLoginTexts map[string]*CustomText
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *CustomLoginTextsReadModel) Reduce() error {
|
||||||
|
for _, event := range wm.Events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *policy.CustomTextSetEvent:
|
||||||
|
wm.CustomLoginTexts[e.Template+e.Language.String()] = &CustomText{Language: e.Language, Template: e.Template}
|
||||||
|
case *policy.CustomTextTemplateRemovedEvent:
|
||||||
|
if _, ok := wm.CustomLoginTexts[e.Template+e.Language.String()]; ok {
|
||||||
|
delete(wm.CustomLoginTexts, e.Template)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wm.WriteModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
type CustomLoginTextReadModel struct {
|
type CustomLoginTextReadModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
@@ -558,6 +577,9 @@ func (wm *CustomLoginTextReadModel) Reduce() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case *policy.CustomTextTemplateRemovedEvent:
|
case *policy.CustomTextTemplateRemovedEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.State = domain.PolicyStateRemoved
|
wm.State = domain.PolicyStateRemoved
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,9 +26,10 @@ type FeaturesWriteModel struct {
|
|||||||
LabelPolicyPrivateLabel bool
|
LabelPolicyPrivateLabel bool
|
||||||
LabelPolicyWatermark bool
|
LabelPolicyWatermark bool
|
||||||
CustomDomain bool
|
CustomDomain bool
|
||||||
CustomText bool
|
|
||||||
PrivacyPolicy bool
|
PrivacyPolicy bool
|
||||||
MetadataUser bool
|
MetadataUser bool
|
||||||
|
CustomTextMessage bool
|
||||||
|
CustomTextLogin bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *FeaturesWriteModel) Reduce() error {
|
func (wm *FeaturesWriteModel) Reduce() error {
|
||||||
@@ -84,12 +85,15 @@ func (wm *FeaturesWriteModel) Reduce() error {
|
|||||||
if e.CustomDomain != nil {
|
if e.CustomDomain != nil {
|
||||||
wm.CustomDomain = *e.CustomDomain
|
wm.CustomDomain = *e.CustomDomain
|
||||||
}
|
}
|
||||||
if e.CustomText != nil {
|
|
||||||
wm.CustomText = *e.CustomText
|
|
||||||
}
|
|
||||||
if e.MetadataUser != nil {
|
if e.MetadataUser != nil {
|
||||||
wm.MetadataUser = *e.MetadataUser
|
wm.MetadataUser = *e.MetadataUser
|
||||||
}
|
}
|
||||||
|
if e.CustomTextMessage != nil {
|
||||||
|
wm.CustomTextMessage = *e.CustomTextMessage
|
||||||
|
}
|
||||||
|
if e.CustomTextLogin != nil {
|
||||||
|
wm.CustomTextLogin = *e.CustomTextLogin
|
||||||
|
}
|
||||||
case *features.FeaturesRemovedEvent:
|
case *features.FeaturesRemovedEvent:
|
||||||
wm.State = domain.FeaturesStateRemoved
|
wm.State = domain.FeaturesStateRemoved
|
||||||
}
|
}
|
||||||
|
@@ -49,9 +49,10 @@ func (c *Commands) setDefaultFeatures(ctx context.Context, existingFeatures *IAM
|
|||||||
features.LabelPolicyPrivateLabel,
|
features.LabelPolicyPrivateLabel,
|
||||||
features.LabelPolicyWatermark,
|
features.LabelPolicyWatermark,
|
||||||
features.CustomDomain,
|
features.CustomDomain,
|
||||||
features.CustomText,
|
|
||||||
features.PrivacyPolicy,
|
features.PrivacyPolicy,
|
||||||
features.MetadataUser,
|
features.MetadataUser,
|
||||||
|
features.CustomTextMessage,
|
||||||
|
features.CustomTextLogin,
|
||||||
)
|
)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
||||||
|
@@ -67,9 +67,10 @@ func (wm *IAMFeaturesWriteModel) NewSetEvent(
|
|||||||
labelPolicyPrivateLabel,
|
labelPolicyPrivateLabel,
|
||||||
labelPolicyWatermark,
|
labelPolicyWatermark,
|
||||||
customDomain,
|
customDomain,
|
||||||
customText,
|
|
||||||
privacyPolicy,
|
privacyPolicy,
|
||||||
metadataUser bool,
|
metadataUser,
|
||||||
|
customTextMessage,
|
||||||
|
customTextLogin bool,
|
||||||
) (*iam.FeaturesSetEvent, bool) {
|
) (*iam.FeaturesSetEvent, bool) {
|
||||||
|
|
||||||
changes := make([]features.FeaturesChanges, 0)
|
changes := make([]features.FeaturesChanges, 0)
|
||||||
@@ -116,15 +117,18 @@ func (wm *IAMFeaturesWriteModel) NewSetEvent(
|
|||||||
if wm.CustomDomain != customDomain {
|
if wm.CustomDomain != customDomain {
|
||||||
changes = append(changes, features.ChangeCustomDomain(customDomain))
|
changes = append(changes, features.ChangeCustomDomain(customDomain))
|
||||||
}
|
}
|
||||||
if wm.CustomText != customText {
|
|
||||||
changes = append(changes, features.ChangeCustomText(customText))
|
|
||||||
}
|
|
||||||
if wm.PrivacyPolicy != privacyPolicy {
|
if wm.PrivacyPolicy != privacyPolicy {
|
||||||
changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
|
changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
|
||||||
}
|
}
|
||||||
if wm.MetadataUser != metadataUser {
|
if wm.MetadataUser != metadataUser {
|
||||||
changes = append(changes, features.ChangeMetadataUser(metadataUser))
|
changes = append(changes, features.ChangeMetadataUser(metadataUser))
|
||||||
}
|
}
|
||||||
|
if wm.CustomTextMessage != customTextMessage {
|
||||||
|
changes = append(changes, features.ChangeCustomTextMessage(customTextMessage))
|
||||||
|
}
|
||||||
|
if wm.CustomTextLogin != customTextLogin {
|
||||||
|
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@@ -67,6 +67,21 @@ func (c *Commands) RemoveOrgLoginTexts(ctx context.Context, resourceOwner string
|
|||||||
return writeModelToObjectDetails(&customText.WriteModel), nil
|
return writeModelToObjectDetails(&customText.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) removeOrgLoginTextsIfExists(ctx context.Context, orgID string) ([]eventstore.EventPusher, error) {
|
||||||
|
msgTemplates := NewOrgCustomLoginTextsReadModel(orgID)
|
||||||
|
err := c.eventstore.FilterToQueryReducer(ctx, msgTemplates)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
orgAgg := OrgAggregateFromWriteModel(&msgTemplates.WriteModel)
|
||||||
|
events := make([]eventstore.EventPusher, 0, len(msgTemplates.CustomLoginTexts))
|
||||||
|
for _, tmpl := range msgTemplates.CustomLoginTexts {
|
||||||
|
events = append(events, org.NewCustomTextTemplateRemovedEvent(ctx, orgAgg, tmpl.Template, tmpl.Language))
|
||||||
|
}
|
||||||
|
return events, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) orgCustomLoginTextWriteModelByID(ctx context.Context, orgID string, lang language.Tag) (*OrgCustomLoginTextReadModel, error) {
|
func (c *Commands) orgCustomLoginTextWriteModelByID(ctx context.Context, orgID string, lang language.Tag) (*OrgCustomLoginTextReadModel, error) {
|
||||||
writeModel := NewOrgCustomLoginTextReadModel(orgID, lang)
|
writeModel := NewOrgCustomLoginTextReadModel(orgID, lang)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
err := c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||||
|
@@ -3,6 +3,7 @@ package command
|
|||||||
import (
|
import (
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
"github.com/caos/zitadel/internal/eventstore"
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
"github.com/caos/zitadel/internal/repository/org"
|
"github.com/caos/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
@@ -27,10 +28,19 @@ func (wm *OrgCustomLoginTextReadModel) AppendEvents(events ...eventstore.EventRe
|
|||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *org.CustomTextSetEvent:
|
case *org.CustomTextSetEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.CustomLoginTextReadModel.AppendEvents(&e.CustomTextSetEvent)
|
wm.CustomLoginTextReadModel.AppendEvents(&e.CustomTextSetEvent)
|
||||||
case *org.CustomTextRemovedEvent:
|
case *org.CustomTextRemovedEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.CustomLoginTextReadModel.AppendEvents(&e.CustomTextRemovedEvent)
|
wm.CustomLoginTextReadModel.AppendEvents(&e.CustomTextRemovedEvent)
|
||||||
case *org.CustomTextTemplateRemovedEvent:
|
case *org.CustomTextTemplateRemovedEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.CustomLoginTextReadModel.AppendEvents(&e.CustomTextTemplateRemovedEvent)
|
wm.CustomLoginTextReadModel.AppendEvents(&e.CustomTextTemplateRemovedEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,3 +62,58 @@ func (wm *OrgCustomLoginTextReadModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
org.CustomTextTemplateRemovedEventType).
|
org.CustomTextTemplateRemovedEventType).
|
||||||
Builder()
|
Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OrgCustomLoginTextsReadModel struct {
|
||||||
|
CustomLoginTextsReadModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOrgCustomLoginTextsReadModel(orgID string) *OrgCustomLoginTextsReadModel {
|
||||||
|
return &OrgCustomLoginTextsReadModel{
|
||||||
|
CustomLoginTextsReadModel{
|
||||||
|
WriteModel: eventstore.WriteModel{
|
||||||
|
AggregateID: orgID,
|
||||||
|
ResourceOwner: orgID,
|
||||||
|
},
|
||||||
|
CustomLoginTexts: make(map[string]*CustomText),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgCustomLoginTextsReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
|
for _, event := range events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *org.CustomTextSetEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.CustomLoginTextsReadModel.AppendEvents(&e.CustomTextSetEvent)
|
||||||
|
case *org.CustomTextRemovedEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.CustomLoginTextsReadModel.AppendEvents(&e.CustomTextRemovedEvent)
|
||||||
|
case *org.CustomTextTemplateRemovedEvent:
|
||||||
|
if e.Template != domain.LoginCustomText {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.CustomLoginTextsReadModel.AppendEvents(&e.CustomTextTemplateRemovedEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgCustomLoginTextsReadModel) Reduce() error {
|
||||||
|
return wm.CustomLoginTextsReadModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgCustomLoginTextsReadModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
ResourceOwner(wm.ResourceOwner).
|
||||||
|
AddQuery().
|
||||||
|
AggregateIDs(wm.CustomLoginTextsReadModel.AggregateID).
|
||||||
|
AggregateTypes(org.AggregateType).
|
||||||
|
EventTypes(
|
||||||
|
org.CustomTextSetEventType,
|
||||||
|
org.CustomTextRemovedEventType,
|
||||||
|
org.CustomTextTemplateRemovedEventType).
|
||||||
|
Builder()
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,7 @@ package command
|
|||||||
import (
|
import (
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
"github.com/caos/zitadel/internal/eventstore"
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
"github.com/caos/zitadel/internal/repository/org"
|
"github.com/caos/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
@@ -74,10 +75,19 @@ func (wm *OrgCustomMessageTemplatesReadModel) AppendEvents(events ...eventstore.
|
|||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *org.CustomTextSetEvent:
|
case *org.CustomTextSetEvent:
|
||||||
|
if !domain.IsMessageTextType(e.Template) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.CustomMessageTemplatesReadModel.AppendEvents(&e.CustomTextSetEvent)
|
wm.CustomMessageTemplatesReadModel.AppendEvents(&e.CustomTextSetEvent)
|
||||||
case *org.CustomTextRemovedEvent:
|
case *org.CustomTextRemovedEvent:
|
||||||
|
if !domain.IsMessageTextType(e.Template) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.CustomMessageTemplatesReadModel.AppendEvents(&e.CustomTextRemovedEvent)
|
wm.CustomMessageTemplatesReadModel.AppendEvents(&e.CustomTextRemovedEvent)
|
||||||
case *org.CustomTextTemplateRemovedEvent:
|
case *org.CustomTextTemplateRemovedEvent:
|
||||||
|
if !domain.IsMessageTextType(e.Template) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
wm.CustomMessageTemplatesReadModel.AppendEvents(&e.CustomTextTemplateRemovedEvent)
|
wm.CustomMessageTemplatesReadModel.AppendEvents(&e.CustomTextTemplateRemovedEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,9 +40,10 @@ func (c *Commands) SetOrgFeatures(ctx context.Context, resourceOwner string, fea
|
|||||||
features.LabelPolicyPrivateLabel,
|
features.LabelPolicyPrivateLabel,
|
||||||
features.LabelPolicyWatermark,
|
features.LabelPolicyWatermark,
|
||||||
features.CustomDomain,
|
features.CustomDomain,
|
||||||
features.CustomText,
|
|
||||||
features.PrivacyPolicy,
|
features.PrivacyPolicy,
|
||||||
features.MetadataUser,
|
features.MetadataUser,
|
||||||
|
features.CustomTextMessage,
|
||||||
|
features.CustomTextLogin,
|
||||||
)
|
)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
||||||
@@ -129,13 +130,22 @@ func (c *Commands) ensureOrgSettingsToFeatures(ctx context.Context, orgID string
|
|||||||
events = append(events, removeCustomDomainsEvents...)
|
events = append(events, removeCustomDomainsEvents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !features.CustomText {
|
if !features.CustomTextMessage {
|
||||||
removeCustomTextEvents, err := c.removeOrgMessageTextsIfExists(ctx, orgID)
|
removeCustomMessageTextEvents, err := c.removeOrgMessageTextsIfExists(ctx, orgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if removeCustomTextEvents != nil {
|
if removeCustomMessageTextEvents != nil {
|
||||||
events = append(events, removeCustomTextEvents...)
|
events = append(events, removeCustomMessageTextEvents...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !features.CustomTextLogin {
|
||||||
|
removeCustomLoginTextEvents, err := c.removeOrgLoginTextsIfExists(ctx, orgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if removeCustomLoginTextEvents != nil {
|
||||||
|
events = append(events, removeCustomLoginTextEvents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !features.PrivacyPolicy {
|
if !features.PrivacyPolicy {
|
||||||
|
@@ -74,9 +74,10 @@ func (wm *OrgFeaturesWriteModel) NewSetEvent(
|
|||||||
labelPolicyPrivateLabel,
|
labelPolicyPrivateLabel,
|
||||||
labelPolicyWatermark,
|
labelPolicyWatermark,
|
||||||
customDomain,
|
customDomain,
|
||||||
customText,
|
|
||||||
privacyPolicy,
|
privacyPolicy,
|
||||||
metadataUser bool,
|
metadataUser,
|
||||||
|
customTextMessage,
|
||||||
|
customTextLogin bool,
|
||||||
) (*org.FeaturesSetEvent, bool) {
|
) (*org.FeaturesSetEvent, bool) {
|
||||||
|
|
||||||
changes := make([]features.FeaturesChanges, 0)
|
changes := make([]features.FeaturesChanges, 0)
|
||||||
@@ -126,15 +127,18 @@ func (wm *OrgFeaturesWriteModel) NewSetEvent(
|
|||||||
if wm.CustomDomain != customDomain {
|
if wm.CustomDomain != customDomain {
|
||||||
changes = append(changes, features.ChangeCustomDomain(customDomain))
|
changes = append(changes, features.ChangeCustomDomain(customDomain))
|
||||||
}
|
}
|
||||||
if wm.CustomText != customText {
|
|
||||||
changes = append(changes, features.ChangeCustomText(customText))
|
|
||||||
}
|
|
||||||
if wm.PrivacyPolicy != privacyPolicy {
|
if wm.PrivacyPolicy != privacyPolicy {
|
||||||
changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
|
changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
|
||||||
}
|
}
|
||||||
if wm.MetadataUser != metadataUser {
|
if wm.MetadataUser != metadataUser {
|
||||||
changes = append(changes, features.ChangeMetadataUser(metadataUser))
|
changes = append(changes, features.ChangeMetadataUser(metadataUser))
|
||||||
}
|
}
|
||||||
|
if wm.CustomTextMessage != customTextMessage {
|
||||||
|
changes = append(changes, features.ChangeCustomTextMessage(customTextMessage))
|
||||||
|
}
|
||||||
|
if wm.CustomTextLogin != customTextLogin {
|
||||||
|
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
|
||||||
|
}
|
||||||
|
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@@ -242,6 +242,18 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPrivacyPolicyAddedEvent(
|
iam.NewPrivacyPolicyAddedEvent(
|
||||||
@@ -280,7 +292,8 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
LabelPolicyPrivateLabel: false,
|
LabelPolicyPrivateLabel: false,
|
||||||
LabelPolicyWatermark: false,
|
LabelPolicyWatermark: false,
|
||||||
CustomDomain: false,
|
CustomDomain: false,
|
||||||
CustomText: false,
|
CustomTextMessage: false,
|
||||||
|
CustomTextLogin: false,
|
||||||
PrivacyPolicy: false,
|
PrivacyPolicy: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
},
|
},
|
||||||
@@ -415,6 +428,18 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPrivacyPolicyAddedEvent(
|
iam.NewPrivacyPolicyAddedEvent(
|
||||||
@@ -600,6 +625,18 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPrivacyPolicyAddedEvent(
|
iam.NewPrivacyPolicyAddedEvent(
|
||||||
@@ -795,6 +832,18 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPrivacyPolicyAddedEvent(
|
iam.NewPrivacyPolicyAddedEvent(
|
||||||
@@ -1045,6 +1094,18 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPrivacyPolicyAddedEvent(
|
org.NewPrivacyPolicyAddedEvent(
|
||||||
@@ -1079,6 +1140,9 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewCustomTextTemplateRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, domain.InitCodeMessageType, language.English),
|
org.NewCustomTextTemplateRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, domain.InitCodeMessageType, language.English),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextTemplateRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, language.English),
|
||||||
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPrivacyPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate),
|
org.NewPrivacyPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate),
|
||||||
),
|
),
|
||||||
@@ -1219,6 +1283,18 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPrivacyPolicyAddedEvent(
|
iam.NewPrivacyPolicyAddedEvent(
|
||||||
@@ -1269,7 +1345,8 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
LabelPolicyPrivateLabel: false,
|
LabelPolicyPrivateLabel: false,
|
||||||
LabelPolicyWatermark: false,
|
LabelPolicyWatermark: false,
|
||||||
CustomDomain: false,
|
CustomDomain: false,
|
||||||
CustomText: false,
|
CustomTextMessage: false,
|
||||||
|
CustomTextLogin: false,
|
||||||
PrivacyPolicy: false,
|
PrivacyPolicy: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
},
|
},
|
||||||
@@ -1452,6 +1529,18 @@ func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewCustomTextSetEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
domain.LoginCustomText,
|
||||||
|
domain.LoginKeyExternalRegistrationUserOverviewTitle,
|
||||||
|
"text",
|
||||||
|
language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPrivacyPolicyAddedEvent(
|
iam.NewPrivacyPolicyAddedEvent(
|
||||||
|
@@ -68,3 +68,12 @@ func (m *MessageTexts) GetMessageTextByType(msgType string) *CustomMessageText {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsMessageTextType(textType string) bool {
|
||||||
|
return textType == InitCodeMessageType ||
|
||||||
|
textType == PasswordResetMessageType ||
|
||||||
|
textType == VerifyEmailMessageType ||
|
||||||
|
textType == VerifyPhoneMessageType ||
|
||||||
|
textType == DomainClaimedMessageType ||
|
||||||
|
textType == PasswordlessRegistrationMessageType
|
||||||
|
}
|
||||||
|
@@ -18,10 +18,12 @@ const (
|
|||||||
FeatureLabelPolicy = "label_policy"
|
FeatureLabelPolicy = "label_policy"
|
||||||
FeatureLabelPolicyPrivateLabel = FeatureLabelPolicy + ".private_label"
|
FeatureLabelPolicyPrivateLabel = FeatureLabelPolicy + ".private_label"
|
||||||
FeatureLabelPolicyWatermark = FeatureLabelPolicy + ".watermark"
|
FeatureLabelPolicyWatermark = FeatureLabelPolicy + ".watermark"
|
||||||
FeatureCustomText = "custom_text"
|
|
||||||
FeatureCustomDomain = "custom_domain"
|
FeatureCustomDomain = "custom_domain"
|
||||||
FeaturePrivacyPolicy = "privacy_policy"
|
FeaturePrivacyPolicy = "privacy_policy"
|
||||||
FeatureMetadata = "metadata"
|
FeatureMetadata = "metadata"
|
||||||
|
FeatureCustomText = "custom_text"
|
||||||
|
FeatureCustomTextMessage = FeatureCustomText + ".message"
|
||||||
|
FeatureCustomTextLogin = FeatureCustomText + ".login"
|
||||||
FeatureMetadataUser = FeatureMetadata + ".user"
|
FeatureMetadataUser = FeatureMetadata + ".user"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +47,8 @@ type Features struct {
|
|||||||
LabelPolicyPrivateLabel bool
|
LabelPolicyPrivateLabel bool
|
||||||
LabelPolicyWatermark bool
|
LabelPolicyWatermark bool
|
||||||
CustomDomain bool
|
CustomDomain bool
|
||||||
CustomText bool
|
CustomTextMessage bool
|
||||||
|
CustomTextLogin bool
|
||||||
PrivacyPolicy bool
|
PrivacyPolicy bool
|
||||||
MetadataUser bool
|
MetadataUser bool
|
||||||
}
|
}
|
||||||
|
@@ -28,9 +28,10 @@ type FeaturesView struct {
|
|||||||
LabelPolicyPrivateLabel bool
|
LabelPolicyPrivateLabel bool
|
||||||
LabelPolicyWatermark bool
|
LabelPolicyWatermark bool
|
||||||
CustomDomain bool
|
CustomDomain bool
|
||||||
CustomText bool
|
|
||||||
PrivacyPolicy bool
|
PrivacyPolicy bool
|
||||||
MetadataUser bool
|
MetadataUser bool
|
||||||
|
CustomTextMessage bool
|
||||||
|
CustomTextLogin bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FeaturesView) FeatureList() []string {
|
func (f *FeaturesView) FeatureList() []string {
|
||||||
@@ -65,15 +66,18 @@ func (f *FeaturesView) FeatureList() []string {
|
|||||||
if f.CustomDomain {
|
if f.CustomDomain {
|
||||||
list = append(list, domain.FeatureCustomDomain)
|
list = append(list, domain.FeatureCustomDomain)
|
||||||
}
|
}
|
||||||
if f.CustomText {
|
|
||||||
list = append(list, domain.FeatureCustomText)
|
|
||||||
}
|
|
||||||
if f.PrivacyPolicy {
|
if f.PrivacyPolicy {
|
||||||
list = append(list, domain.FeaturePrivacyPolicy)
|
list = append(list, domain.FeaturePrivacyPolicy)
|
||||||
}
|
}
|
||||||
if f.MetadataUser {
|
if f.MetadataUser {
|
||||||
list = append(list, domain.FeatureMetadataUser)
|
list = append(list, domain.FeatureMetadataUser)
|
||||||
}
|
}
|
||||||
|
if f.CustomTextMessage {
|
||||||
|
list = append(list, domain.FeatureCustomTextMessage)
|
||||||
|
}
|
||||||
|
if f.CustomTextLogin {
|
||||||
|
list = append(list, domain.FeatureCustomTextLogin)
|
||||||
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,9 +42,10 @@ type FeaturesView struct {
|
|||||||
LabelPolicyPrivateLabel bool `json:"labelPolicyPrivateLabel" gorm:"column:label_policy_private_label"`
|
LabelPolicyPrivateLabel bool `json:"labelPolicyPrivateLabel" gorm:"column:label_policy_private_label"`
|
||||||
LabelPolicyWatermark bool `json:"labelPolicyWatermark" gorm:"column:label_policy_watermark"`
|
LabelPolicyWatermark bool `json:"labelPolicyWatermark" gorm:"column:label_policy_watermark"`
|
||||||
CustomDomain bool `json:"customDomain" gorm:"column:custom_domain"`
|
CustomDomain bool `json:"customDomain" gorm:"column:custom_domain"`
|
||||||
CustomText bool `json:"customText" gorm:"column:custom_text"`
|
|
||||||
PrivacyPolicy bool `json:"privacyPolicy" gorm:"column:privacy_policy"`
|
PrivacyPolicy bool `json:"privacyPolicy" gorm:"column:privacy_policy"`
|
||||||
MetadataUser bool `json:"metadataUser" gorm:"column:metadata_user"`
|
MetadataUser bool `json:"metadataUser" gorm:"column:metadata_user"`
|
||||||
|
CustomTextMessage bool `json:"customTextMessage" gorm:"column:custom_text_message"`
|
||||||
|
CustomTextLogin bool `json:"customTextLogin" gorm:"column:custom_text_login"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func FeaturesToModel(features *FeaturesView) *features_model.FeaturesView {
|
func FeaturesToModel(features *FeaturesView) *features_model.FeaturesView {
|
||||||
@@ -69,9 +70,10 @@ func FeaturesToModel(features *FeaturesView) *features_model.FeaturesView {
|
|||||||
LabelPolicyPrivateLabel: features.LabelPolicyPrivateLabel,
|
LabelPolicyPrivateLabel: features.LabelPolicyPrivateLabel,
|
||||||
LabelPolicyWatermark: features.LabelPolicyWatermark,
|
LabelPolicyWatermark: features.LabelPolicyWatermark,
|
||||||
CustomDomain: features.CustomDomain,
|
CustomDomain: features.CustomDomain,
|
||||||
CustomText: features.CustomText,
|
|
||||||
PrivacyPolicy: features.PrivacyPolicy,
|
PrivacyPolicy: features.PrivacyPolicy,
|
||||||
MetadataUser: features.MetadataUser,
|
MetadataUser: features.MetadataUser,
|
||||||
|
CustomTextMessage: features.CustomTextMessage,
|
||||||
|
CustomTextLogin: features.CustomTextLogin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,9 +35,10 @@ type FeaturesSetEvent struct {
|
|||||||
LabelPolicyPrivateLabel *bool `json:"labelPolicyPrivateLabel,omitempty"`
|
LabelPolicyPrivateLabel *bool `json:"labelPolicyPrivateLabel,omitempty"`
|
||||||
LabelPolicyWatermark *bool `json:"labelPolicyWatermark,omitempty"`
|
LabelPolicyWatermark *bool `json:"labelPolicyWatermark,omitempty"`
|
||||||
CustomDomain *bool `json:"customDomain,omitempty"`
|
CustomDomain *bool `json:"customDomain,omitempty"`
|
||||||
CustomText *bool `json:"customText,omitempty"`
|
|
||||||
PrivacyPolicy *bool `json:"privacyPolicy,omitempty"`
|
PrivacyPolicy *bool `json:"privacyPolicy,omitempty"`
|
||||||
MetadataUser *bool `json:"metadataUser,omitempty"`
|
MetadataUser *bool `json:"metadataUser,omitempty"`
|
||||||
|
CustomTextMessage *bool `json:"customTextMessage,omitempty"`
|
||||||
|
CustomTextLogin *bool `json:"customTextLogin,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *FeaturesSetEvent) Data() interface{} {
|
func (e *FeaturesSetEvent) Data() interface{} {
|
||||||
@@ -156,12 +157,6 @@ func ChangeCustomDomain(customDomain bool) func(event *FeaturesSetEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChangeCustomText(customText bool) func(event *FeaturesSetEvent) {
|
|
||||||
return func(e *FeaturesSetEvent) {
|
|
||||||
e.CustomText = &customText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ChangePrivacyPolicy(privacyPolicy bool) func(event *FeaturesSetEvent) {
|
func ChangePrivacyPolicy(privacyPolicy bool) func(event *FeaturesSetEvent) {
|
||||||
return func(e *FeaturesSetEvent) {
|
return func(e *FeaturesSetEvent) {
|
||||||
e.PrivacyPolicy = &privacyPolicy
|
e.PrivacyPolicy = &privacyPolicy
|
||||||
@@ -173,6 +168,19 @@ func ChangeMetadataUser(metadataUser bool) func(event *FeaturesSetEvent) {
|
|||||||
e.MetadataUser = &metadataUser
|
e.MetadataUser = &metadataUser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeCustomTextMessage(customTextMessage bool) func(event *FeaturesSetEvent) {
|
||||||
|
return func(e *FeaturesSetEvent) {
|
||||||
|
e.CustomTextMessage = &customTextMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeCustomTextLogin(customTextLogin bool) func(event *FeaturesSetEvent) {
|
||||||
|
return func(e *FeaturesSetEvent) {
|
||||||
|
e.CustomTextLogin = &customTextLogin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func FeaturesSetEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func FeaturesSetEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e := &FeaturesSetEvent{
|
e := &FeaturesSetEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
9
migrations/cockroach/V1.62__custom_text_feature.sql
Normal file
9
migrations/cockroach/V1.62__custom_text_feature.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
ALTER TABLE adminapi.features RENAME COLUMN custom_text TO custom_text_message;
|
||||||
|
ALTER TABLE auth.features RENAME COLUMN custom_text TO custom_text_message;
|
||||||
|
ALTER TABLE authz.features RENAME COLUMN custom_text TO custom_text_message;
|
||||||
|
ALTER TABLE management.features RENAME COLUMN custom_text TO custom_text_message;
|
||||||
|
|
||||||
|
ALTER TABLE adminapi.features ADD COLUMN custom_text_login BOOLEAN;
|
||||||
|
ALTER TABLE auth.features ADD COLUMN custom_text_login BOOLEAN;
|
||||||
|
ALTER TABLE authz.features ADD COLUMN custom_text_login BOOLEAN;
|
||||||
|
ALTER TABLE management.features ADD COLUMN custom_text_login BOOLEAN;
|
@@ -2613,6 +2613,8 @@ message SetDefaultFeaturesRequest {
|
|||||||
bool custom_text = 17;
|
bool custom_text = 17;
|
||||||
bool privacy_policy = 18;
|
bool privacy_policy = 18;
|
||||||
bool metadata_user = 19;
|
bool metadata_user = 19;
|
||||||
|
bool custom_text_message = 20;
|
||||||
|
bool custom_text_login = 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetDefaultFeaturesResponse {
|
message SetDefaultFeaturesResponse {
|
||||||
@@ -2649,6 +2651,8 @@ message SetOrgFeaturesRequest {
|
|||||||
bool custom_text = 18;
|
bool custom_text = 18;
|
||||||
bool privacy_policy = 19;
|
bool privacy_policy = 19;
|
||||||
bool metadata_user = 20;
|
bool metadata_user = 20;
|
||||||
|
bool custom_text_message = 21;
|
||||||
|
bool custom_text_login = 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetOrgFeaturesResponse {
|
message SetOrgFeaturesResponse {
|
||||||
|
@@ -27,6 +27,8 @@ message Features {
|
|||||||
bool custom_text = 16;
|
bool custom_text = 16;
|
||||||
bool privacy_policy = 17;
|
bool privacy_policy = 17;
|
||||||
bool metadata_user = 18;
|
bool metadata_user = 18;
|
||||||
|
bool custom_text_message = 19;
|
||||||
|
bool custom_text_login = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FeatureTier {
|
message FeatureTier {
|
||||||
|
@@ -2271,7 +2271,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.message"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2319,7 +2319,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.message"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2368,7 +2368,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.message"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2417,7 +2417,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.message"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2466,7 +2466,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.message"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2515,7 +2515,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.message"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2563,7 +2563,7 @@ service ManagementService {
|
|||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
permission: "policy.write";
|
permission: "policy.write";
|
||||||
feature: "custom_text"
|
feature: "custom_text.login"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user