mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-08 15:57:40 +00:00
feat: add Help/Support e-mail for instance/org (#5445)
feat: help and support email in privacy policy
This commit is contained in:
parent
12a7c4b994
commit
1b9cea0e0c
@ -499,6 +499,7 @@ DefaultInstance:
|
|||||||
TOSLink: https://zitadel.com/docs/legal/terms-of-service
|
TOSLink: https://zitadel.com/docs/legal/terms-of-service
|
||||||
PrivacyLink: https://zitadel.com/docs/legal/privacy-policy
|
PrivacyLink: https://zitadel.com/docs/legal/privacy-policy
|
||||||
HelpLink: ""
|
HelpLink: ""
|
||||||
|
SupportEmail: ""
|
||||||
NotificationPolicy:
|
NotificationPolicy:
|
||||||
PasswordChange: true
|
PasswordChange: true
|
||||||
LabelPolicy:
|
LabelPolicy:
|
||||||
|
@ -73,6 +73,7 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
|||||||
r3.setHelp(map.footerText?.help ?? '');
|
r3.setHelp(map.footerText?.help ?? '');
|
||||||
r3.setPrivacyPolicy(map.footerText?.privacyPolicy ?? '');
|
r3.setPrivacyPolicy(map.footerText?.privacyPolicy ?? '');
|
||||||
r3.setTos(map.footerText?.tos ?? '');
|
r3.setTos(map.footerText?.tos ?? '');
|
||||||
|
r3.setSupportEmail(map.footerText?.supportEmail ?? '');
|
||||||
req.setFooterText(r3);
|
req.setFooterText(r3);
|
||||||
|
|
||||||
const r4 = new InitMFADoneScreenText();
|
const r4 = new InitMFADoneScreenText();
|
||||||
|
@ -36,6 +36,12 @@
|
|||||||
<input cnslInput name="helpLink" formControlName="helpLink" />
|
<input cnslInput name="helpLink" formControlName="helpLink" />
|
||||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'helpLink' }"></template>
|
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'helpLink' }"></template>
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
|
<cnsl-form-field class="privacy-policy-formfield">
|
||||||
|
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.SUPPORTEMAIL' | translate }}</cnsl-label>
|
||||||
|
<input cnslInput name="supportEmail" formControlName="supportEmail" />
|
||||||
|
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'supportEmail' }"></template>
|
||||||
|
</cnsl-form-field>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
column-gap: 1rem;
|
column-gap: 1rem;
|
||||||
|
width: 75%;
|
||||||
|
|
||||||
@media only screen and (min-width: 800px) {
|
@media only screen and (min-width: 800px) {
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
|||||||
tosLink: ['', []],
|
tosLink: ['', []],
|
||||||
privacyLink: ['', []],
|
privacyLink: ['', []],
|
||||||
helpLink: ['', []],
|
helpLink: ['', []],
|
||||||
|
supportEmail: ['', []],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.canWrite$.pipe(take(1)).subscribe((canWrite) => {
|
this.canWrite$.pipe(take(1)).subscribe((canWrite) => {
|
||||||
@ -105,6 +106,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
|||||||
tosLink: '',
|
tosLink: '',
|
||||||
privacyLink: '',
|
privacyLink: '',
|
||||||
helpLink: '',
|
helpLink: '',
|
||||||
|
supportEmail: '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -114,6 +116,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
|||||||
tosLink: '',
|
tosLink: '',
|
||||||
privacyLink: '',
|
privacyLink: '',
|
||||||
helpLink: '',
|
helpLink: '',
|
||||||
|
supportEmail: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -125,6 +128,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
|||||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||||
req.setTosLink(this.form.get('tosLink')?.value);
|
req.setTosLink(this.form.get('tosLink')?.value);
|
||||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||||
|
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||||
(this.service as ManagementService)
|
(this.service as ManagementService)
|
||||||
.addCustomPrivacyPolicy(req)
|
.addCustomPrivacyPolicy(req)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -137,6 +141,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
|||||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||||
req.setTosLink(this.form.get('tosLink')?.value);
|
req.setTosLink(this.form.get('tosLink')?.value);
|
||||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||||
|
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||||
|
|
||||||
(this.service as ManagementService)
|
(this.service as ManagementService)
|
||||||
.updateCustomPrivacyPolicy(req)
|
.updateCustomPrivacyPolicy(req)
|
||||||
@ -151,6 +156,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
|||||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||||
req.setTosLink(this.form.get('tosLink')?.value);
|
req.setTosLink(this.form.get('tosLink')?.value);
|
||||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||||
|
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||||
|
|
||||||
(this.service as AdminService)
|
(this.service as AdminService)
|
||||||
.updatePrivacyPolicy(req)
|
.updatePrivacyPolicy(req)
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
<cnsl-login-texts [serviceType]="serviceType"></cnsl-login-texts>
|
<cnsl-login-texts [serviceType]="serviceType"></cnsl-login-texts>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="currentSetting === 'privacypolicy'">
|
<ng-container *ngIf="currentSetting === 'privacypolicy'">
|
||||||
<cnsl-privacy-policy [serviceType]="PolicyComponentServiceType.ADMIN"></cnsl-privacy-policy>
|
<cnsl-privacy-policy [serviceType]="serviceType"></cnsl-privacy-policy>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</cnsl-sidenav>
|
</cnsl-sidenav>
|
||||||
|
@ -1185,6 +1185,7 @@
|
|||||||
"TOSLINK": "Link zu den Allgemeinen Geschäftsbedingungen",
|
"TOSLINK": "Link zu den Allgemeinen Geschäftsbedingungen",
|
||||||
"POLICYLINK": "Link zur den Datenschutzrichtlinien",
|
"POLICYLINK": "Link zur den Datenschutzrichtlinien",
|
||||||
"HELPLINK": "Link zur Hilfestellung",
|
"HELPLINK": "Link zur Hilfestellung",
|
||||||
|
"SUPPORTEMAIL": "Support E-Mail",
|
||||||
"SAVED": "Saved successfully!",
|
"SAVED": "Saved successfully!",
|
||||||
"RESET_TITLE": "Standardwerte wiederherstellen",
|
"RESET_TITLE": "Standardwerte wiederherstellen",
|
||||||
"RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
|
"RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
|
||||||
|
@ -1186,6 +1186,7 @@
|
|||||||
"TOSLINK": "Link to Terms of Service",
|
"TOSLINK": "Link to Terms of Service",
|
||||||
"POLICYLINK": "Link to Privacy Policy",
|
"POLICYLINK": "Link to Privacy Policy",
|
||||||
"HELPLINK": "Link to Help",
|
"HELPLINK": "Link to Help",
|
||||||
|
"SUPPORTEMAIL": "Support Email",
|
||||||
"SAVED": "Saved successfully!",
|
"SAVED": "Saved successfully!",
|
||||||
"RESET_TITLE": "Restore Default Values",
|
"RESET_TITLE": "Restore Default Values",
|
||||||
"RESET_DESCRIPTION": "You are about to restore the default Links for TOS and Privacy Policy. Do you really want to continue?"
|
"RESET_DESCRIPTION": "You are about to restore the default Links for TOS and Privacy Policy. Do you really want to continue?"
|
||||||
|
@ -1185,6 +1185,7 @@
|
|||||||
"TOSLINK": "Lien vers les conditions d'utilisation",
|
"TOSLINK": "Lien vers les conditions d'utilisation",
|
||||||
"POLICYLINK": "Lien vers la politique de confidentialité",
|
"POLICYLINK": "Lien vers la politique de confidentialité",
|
||||||
"HELPLINK": "Lien vers l'aide",
|
"HELPLINK": "Lien vers l'aide",
|
||||||
|
"SUPPORTEMAIL": "E-mail d'assistance",
|
||||||
"SAVED": "Enregistré avec succès !",
|
"SAVED": "Enregistré avec succès !",
|
||||||
"RESET_TITLE": "Restaurer les valeurs par défaut",
|
"RESET_TITLE": "Restaurer les valeurs par défaut",
|
||||||
"RESET_DESCRIPTION": "Vous êtes sur le point de restaurer les liens par défaut pour les CGS et la politique de confidentialité. Voulez-vous vraiment continuer ?"
|
"RESET_DESCRIPTION": "Vous êtes sur le point de restaurer les liens par défaut pour les CGS et la politique de confidentialité. Voulez-vous vraiment continuer ?"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"FOOTER": {
|
"FOOTER": {
|
||||||
"LINKS": {
|
"LINKS": {
|
||||||
"CONTACT": "Kontakt",
|
"CONTACT": "Contatto",
|
||||||
"TOS": "Terms of Service",
|
"TOS": "Terms of Service",
|
||||||
"PP": "Privacy Policy"
|
"PP": "Privacy Policy"
|
||||||
},
|
},
|
||||||
@ -1186,6 +1186,7 @@
|
|||||||
"TOSLINK": "Link ai termini di servizio",
|
"TOSLINK": "Link ai termini di servizio",
|
||||||
"POLICYLINK": "Link all'informativa sulla privacy",
|
"POLICYLINK": "Link all'informativa sulla privacy",
|
||||||
"HELPLINK": "link per l'aiuto",
|
"HELPLINK": "link per l'aiuto",
|
||||||
|
"SUPPORTEMAIL": "e-mail di supporto",
|
||||||
"SAVED": "Salvato con successo!",
|
"SAVED": "Salvato con successo!",
|
||||||
"RESET_TITLE": "Ripristina i valori predefiniti",
|
"RESET_TITLE": "Ripristina i valori predefiniti",
|
||||||
"RESET_DESCRIPTION": "Stai per ripristinare i link predefiniti per i TOS e l'informativa sulla privacy. Vuoi davvero continuare?"
|
"RESET_DESCRIPTION": "Stai per ripristinare i link predefiniti per i TOS e l'informativa sulla privacy. Vuoi davvero continuare?"
|
||||||
|
@ -1185,6 +1185,7 @@
|
|||||||
"TOSLINK": "Link do warunków korzystania",
|
"TOSLINK": "Link do warunków korzystania",
|
||||||
"POLICYLINK": "Link do polityki prywatności",
|
"POLICYLINK": "Link do polityki prywatności",
|
||||||
"HELPLINK": "Link do pomocy",
|
"HELPLINK": "Link do pomocy",
|
||||||
|
"SUPPORTEMAIL": "E-mail wsparcia",
|
||||||
"SAVED": "Pomyślnie zapisano!",
|
"SAVED": "Pomyślnie zapisano!",
|
||||||
"RESET_TITLE": "Przywróć wartości domyślne",
|
"RESET_TITLE": "Przywróć wartości domyślne",
|
||||||
"RESET_DESCRIPTION": "Masz zamiar przywrócić domyślne linki dla TOS i polityki prywatności. Czy na pewno chcesz kontynuować?"
|
"RESET_DESCRIPTION": "Masz zamiar przywrócić domyślne linki dla TOS i polityki prywatności. Czy na pewno chcesz kontynuować?"
|
||||||
|
@ -1184,6 +1184,7 @@
|
|||||||
"TOSLINK": "链接到服务条款",
|
"TOSLINK": "链接到服务条款",
|
||||||
"POLICYLINK": "链接到隐私政策",
|
"POLICYLINK": "链接到隐私政策",
|
||||||
"HELPLINK": "链接到帮助",
|
"HELPLINK": "链接到帮助",
|
||||||
|
"SUPPORTEMAIL": "支持邮箱",
|
||||||
"SAVED": "保存成功!",
|
"SAVED": "保存成功!",
|
||||||
"RESET_TITLE": "恢复默认值",
|
"RESET_TITLE": "恢复默认值",
|
||||||
"RESET_DESCRIPTION": "您即将恢复 TOS 和隐私政策的默认链接。你真的要继续吗?"
|
"RESET_DESCRIPTION": "您即将恢复 TOS 和隐私政策的默认链接。你真的要继续吗?"
|
||||||
|
@ -57,7 +57,11 @@ At the moment Twilio is available as SMS provider.
|
|||||||
|
|
||||||
You can configure on which changes the users will be notified. The text of the message can be changed in the [Message texts](#message-texts)
|
You can configure on which changes the users will be notified. The text of the message can be changed in the [Message texts](#message-texts)
|
||||||
|
|
||||||
<img src="/docs/img/guides/console/notification.png" alt="Notification" width="400px" />
|
<img
|
||||||
|
src="/docs/img/guides/console/notification.png"
|
||||||
|
alt="Notification"
|
||||||
|
width="400px"
|
||||||
|
/>
|
||||||
|
|
||||||
### SMTP
|
### SMTP
|
||||||
|
|
||||||
@ -132,7 +136,6 @@ Configure the different lifetimes checks for the login process:
|
|||||||
- **Second Factor Check Lifetime** specifies after which period a user has to revalidate the 2-Factor during the login process
|
- **Second Factor Check Lifetime** specifies after which period a user has to revalidate the 2-Factor during the login process
|
||||||
- **External Login Check Lifetime** specifies after which period a user has to revalidate the Multi Factor during the login process
|
- **External Login Check Lifetime** specifies after which period a user has to revalidate the Multi Factor during the login process
|
||||||
|
|
||||||
|
|
||||||
## Identity Providers
|
## Identity Providers
|
||||||
|
|
||||||
You can configure all kinds of external identity providers for identity brokering, which support OIDC (OpenID Connect).
|
You can configure all kinds of external identity providers for identity brokering, which support OIDC (OpenID Connect).
|
||||||
@ -190,7 +193,7 @@ You can either set this attribute on your whole ZITADEL instance or just on some
|
|||||||
|
|
||||||
## Privacy Policy and TOS
|
## Privacy Policy and TOS
|
||||||
|
|
||||||
With this setting you are able to configure your privacy policy, terms of service and help links.
|
With this setting you are able to configure your privacy policy, terms of service, help links and help/support email address.
|
||||||
On register each user has to accept these policies.
|
On register each user has to accept these policies.
|
||||||
|
|
||||||
This policy can be also be overriden by your organizations.
|
This policy can be also be overriden by your organizations.
|
||||||
@ -231,7 +234,11 @@ You can set the locale of the translations on the right.
|
|||||||
|
|
||||||
These are the texts for the login. Just like for message texts, you can select the locale on the right.
|
These are the texts for the login. Just like for message texts, you can select the locale on the right.
|
||||||
|
|
||||||
<img src="/docs/img/guides/console/logintexts.png" alt="Login texts" width="600px" />
|
<img
|
||||||
|
src="/docs/img/guides/console/logintexts.png"
|
||||||
|
alt="Login texts"
|
||||||
|
width="600px"
|
||||||
|
/>
|
||||||
|
|
||||||
## OIDC token lifetimes and expiration
|
## OIDC token lifetimes and expiration
|
||||||
|
|
||||||
|
BIN
docs/static/img/guides/console/privacypolicy.png
vendored
BIN
docs/static/img/guides/console/privacypolicy.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 28 KiB |
@ -524,6 +524,7 @@ func (s *Server) getPrivacyPolicy(ctx context.Context, orgID string) (_ *managem
|
|||||||
TosLink: queriedPrivacy.TOSLink,
|
TosLink: queriedPrivacy.TOSLink,
|
||||||
PrivacyLink: queriedPrivacy.PrivacyLink,
|
PrivacyLink: queriedPrivacy.PrivacyLink,
|
||||||
HelpLink: queriedPrivacy.HelpLink,
|
HelpLink: queriedPrivacy.HelpLink,
|
||||||
|
SupportEmail: string(queriedPrivacy.SupportEmail),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -10,5 +10,6 @@ func UpdatePrivacyPolicyToDomain(req *admin_pb.UpdatePrivacyPolicyRequest) *doma
|
|||||||
TOSLink: req.TosLink,
|
TOSLink: req.TosLink,
|
||||||
PrivacyLink: req.PrivacyLink,
|
PrivacyLink: req.PrivacyLink,
|
||||||
HelpLink: req.HelpLink,
|
HelpLink: req.HelpLink,
|
||||||
|
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ func AddPrivacyPolicyToDomain(req *mgmt_pb.AddCustomPrivacyPolicyRequest) *domai
|
|||||||
TOSLink: req.TosLink,
|
TOSLink: req.TosLink,
|
||||||
PrivacyLink: req.PrivacyLink,
|
PrivacyLink: req.PrivacyLink,
|
||||||
HelpLink: req.HelpLink,
|
HelpLink: req.HelpLink,
|
||||||
|
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,5 +19,6 @@ func UpdatePrivacyPolicyToDomain(req *mgmt_pb.UpdateCustomPrivacyPolicyRequest)
|
|||||||
TOSLink: req.TosLink,
|
TOSLink: req.TosLink,
|
||||||
PrivacyLink: req.PrivacyLink,
|
PrivacyLink: req.PrivacyLink,
|
||||||
HelpLink: req.HelpLink,
|
HelpLink: req.HelpLink,
|
||||||
|
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ func ModelPrivacyPolicyToPb(policy *query.PrivacyPolicy) *policy_pb.PrivacyPolic
|
|||||||
TosLink: policy.TOSLink,
|
TosLink: policy.TOSLink,
|
||||||
PrivacyLink: policy.PrivacyLink,
|
PrivacyLink: policy.PrivacyLink,
|
||||||
HelpLink: policy.HelpLink,
|
HelpLink: policy.HelpLink,
|
||||||
|
SupportEmail: string(policy.SupportEmail),
|
||||||
Details: object.ToViewDetailsPb(
|
Details: object.ToViewDetailsPb(
|
||||||
policy.Sequence,
|
policy.Sequence,
|
||||||
policy.CreationDate,
|
policy.CreationDate,
|
||||||
|
@ -458,6 +458,7 @@ func FooterTextToPb(text domain.FooterText) *text_pb.FooterText {
|
|||||||
Tos: text.TOS,
|
Tos: text.TOS,
|
||||||
PrivacyPolicy: text.PrivacyPolicy,
|
PrivacyPolicy: text.PrivacyPolicy,
|
||||||
Help: text.Help,
|
Help: text.Help,
|
||||||
|
SupportEmail: text.SupportEmail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,5 +950,6 @@ func FooterTextPbToDomain(text *text_pb.FooterText) domain.FooterText {
|
|||||||
TOS: text.Tos,
|
TOS: text.Tos,
|
||||||
PrivacyPolicy: text.PrivacyPolicy,
|
PrivacyPolicy: text.PrivacyPolicy,
|
||||||
Help: text.Help,
|
Help: text.Help,
|
||||||
|
SupportEmail: text.SupportEmail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,6 +442,9 @@ func (l *Login) setLinksOnBaseData(baseData baseData, privacyPolicy *domain.Priv
|
|||||||
if link, err := templates.ParseTemplateText(privacyPolicy.HelpLink, lang); err == nil {
|
if link, err := templates.ParseTemplateText(privacyPolicy.HelpLink, lang); err == nil {
|
||||||
baseData.HelpLink = link
|
baseData.HelpLink = link
|
||||||
}
|
}
|
||||||
|
if link, err := templates.ParseTemplateText(string(privacyPolicy.SupportEmail), lang); err == nil {
|
||||||
|
baseData.SupportEmail = link
|
||||||
|
}
|
||||||
return baseData
|
return baseData
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,6 +605,7 @@ type baseData struct {
|
|||||||
TOSLink string
|
TOSLink string
|
||||||
PrivacyLink string
|
PrivacyLink string
|
||||||
HelpLink string
|
HelpLink string
|
||||||
|
SupportEmail string
|
||||||
AuthReqID string
|
AuthReqID string
|
||||||
CSRF template.HTML
|
CSRF template.HTML
|
||||||
Nonce string
|
Nonce string
|
||||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
|||||||
NewPasswordConfirmLabel: Passwort Bestätigung
|
NewPasswordConfirmLabel: Passwort Bestätigung
|
||||||
CancelButtonText: abbrechen
|
CancelButtonText: abbrechen
|
||||||
NextButtonText: weiter
|
NextButtonText: weiter
|
||||||
|
Footer: Fusszeile
|
||||||
|
|
||||||
PasswordChangeDone:
|
PasswordChangeDone:
|
||||||
Title: Passwort ändern
|
Title: Passwort ändern
|
||||||
@ -318,6 +319,7 @@ Footer:
|
|||||||
Tos: AGB
|
Tos: AGB
|
||||||
PrivacyPolicy: Datenschutzerklärung
|
PrivacyPolicy: Datenschutzerklärung
|
||||||
Help: Hilfe
|
Help: Hilfe
|
||||||
|
SupportEmail: Support E-Mail
|
||||||
|
|
||||||
Errors:
|
Errors:
|
||||||
Internal: Es ist ein interner Fehler aufgetreten
|
Internal: Es ist ein interner Fehler aufgetreten
|
||||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
|||||||
NewPasswordConfirmLabel: Password confirmation
|
NewPasswordConfirmLabel: Password confirmation
|
||||||
CancelButtonText: cancel
|
CancelButtonText: cancel
|
||||||
NextButtonText: next
|
NextButtonText: next
|
||||||
|
Footer: Footer
|
||||||
|
|
||||||
PasswordChangeDone:
|
PasswordChangeDone:
|
||||||
Title: Change Password
|
Title: Change Password
|
||||||
@ -318,6 +319,7 @@ Footer:
|
|||||||
Tos: TOS
|
Tos: TOS
|
||||||
PrivacyPolicy: Privacy policy
|
PrivacyPolicy: Privacy policy
|
||||||
Help: Help
|
Help: Help
|
||||||
|
SupportEmail: Support E-mail
|
||||||
|
|
||||||
Errors:
|
Errors:
|
||||||
Internal: An internal error occurred
|
Internal: An internal error occurred
|
||||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
|||||||
NewPasswordConfirmLabel: Confirmation du mot de passe
|
NewPasswordConfirmLabel: Confirmation du mot de passe
|
||||||
CancelButtonText: annuler
|
CancelButtonText: annuler
|
||||||
NextButtonText: suivant
|
NextButtonText: suivant
|
||||||
|
Footer: Bas de page
|
||||||
|
|
||||||
PasswordChangeDone:
|
PasswordChangeDone:
|
||||||
Title: Changer le mot de passe
|
Title: Changer le mot de passe
|
||||||
@ -318,6 +319,7 @@ Footer:
|
|||||||
Tos: TOS
|
Tos: TOS
|
||||||
PrivacyPolicy: Politique de confidentialité
|
PrivacyPolicy: Politique de confidentialité
|
||||||
Help: Aide
|
Help: Aide
|
||||||
|
SupportEmail: E-mail d'assistance
|
||||||
|
|
||||||
Errors:
|
Errors:
|
||||||
Internal: Une erreur interne s'est produite
|
Internal: Une erreur interne s'est produite
|
||||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
|||||||
NewPasswordConfirmLabel: Conferma della password
|
NewPasswordConfirmLabel: Conferma della password
|
||||||
CancelButtonText: annulla
|
CancelButtonText: annulla
|
||||||
NextButtonText: Avanti
|
NextButtonText: Avanti
|
||||||
|
Footer: Piè di pagina
|
||||||
|
|
||||||
PasswordChangeDone:
|
PasswordChangeDone:
|
||||||
Title: Reimposta password
|
Title: Reimposta password
|
||||||
@ -318,6 +319,7 @@ Footer:
|
|||||||
Tos: Termini di servizio
|
Tos: Termini di servizio
|
||||||
PrivacyPolicy: l'informativa sulla privacy
|
PrivacyPolicy: l'informativa sulla privacy
|
||||||
Help: Aiuto
|
Help: Aiuto
|
||||||
|
SupportEmail: E-mail di supporto
|
||||||
|
|
||||||
Errors:
|
Errors:
|
||||||
Internal: Si è verificato un errore interno
|
Internal: Si è verificato un errore interno
|
||||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
|||||||
NewPasswordConfirmLabel: Potwierdzenie hasła
|
NewPasswordConfirmLabel: Potwierdzenie hasła
|
||||||
CancelButtonText: anuluj
|
CancelButtonText: anuluj
|
||||||
NextButtonText: dalej
|
NextButtonText: dalej
|
||||||
|
Footer: Stopka
|
||||||
|
|
||||||
PasswordChangeDone:
|
PasswordChangeDone:
|
||||||
Title: Zmiana hasła
|
Title: Zmiana hasła
|
||||||
@ -318,6 +319,7 @@ Footer:
|
|||||||
Tos: TOS
|
Tos: TOS
|
||||||
PrivacyPolicy: Polityka prywatności
|
PrivacyPolicy: Polityka prywatności
|
||||||
Help: Pomoc
|
Help: Pomoc
|
||||||
|
SupportEmail: E-mail wsparcia
|
||||||
|
|
||||||
Errors:
|
Errors:
|
||||||
Internal: Wewnętrzny błąd
|
Internal: Wewnętrzny błąd
|
||||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
|||||||
NewPasswordConfirmLabel: 确认密码
|
NewPasswordConfirmLabel: 确认密码
|
||||||
CancelButtonText: 取消
|
CancelButtonText: 取消
|
||||||
NextButtonText: 继续
|
NextButtonText: 继续
|
||||||
|
Footer: 页脚
|
||||||
|
|
||||||
PasswordChangeDone:
|
PasswordChangeDone:
|
||||||
Title: 更改密码
|
Title: 更改密码
|
||||||
@ -318,6 +319,7 @@ Footer:
|
|||||||
Tos: 服务条款
|
Tos: 服务条款
|
||||||
PrivacyPolicy: 隐私政策
|
PrivacyPolicy: 隐私政策
|
||||||
Help: 帮助
|
Help: 帮助
|
||||||
|
SupportEmail: 支持邮箱
|
||||||
|
|
||||||
Errors:
|
Errors:
|
||||||
Internal: 发生了内部错误
|
Internal: 发生了内部错误
|
||||||
|
@ -3,18 +3,39 @@
|
|||||||
{{ if hasWatermark .LabelPolicy }}
|
{{ if hasWatermark .LabelPolicy }}
|
||||||
<span class="watermark">
|
<span class="watermark">
|
||||||
<span class="powered">{{t "Footer.PoweredBy"}}</span>
|
<span class="powered">{{t "Footer.PoweredBy"}}</span>
|
||||||
<span class="lgn-logo-watermark" sourcelight="logo-light.svg" sourcedark="logo-dark.svg" alt="logo"></span>
|
<span
|
||||||
|
class="lgn-logo-watermark"
|
||||||
|
sourcelight="logo-light.svg"
|
||||||
|
sourcedark="logo-dark.svg"
|
||||||
|
alt="logo"
|
||||||
|
></span>
|
||||||
</span>
|
</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
{{ if .TOSLink }}
|
{{ if .TOSLink }}
|
||||||
<a href="{{.TOSLink}}" rel="noopener noreferrer" target="_blank" alt="TOS">{{t "Footer.Tos"}}</a>
|
<a href="{{.TOSLink}}" rel="noopener noreferrer" target="_blank" alt="TOS"
|
||||||
{{ end }}
|
>{{t "Footer.Tos"}}</a
|
||||||
{{ if .PrivacyLink }}
|
>
|
||||||
<a href="{{.PrivacyLink}}" rel="noopener noreferrer" target="_blank" alt="Privacy Policy">{{t "Footer.PrivacyPolicy"}}</a>
|
{{ end }} {{ if .PrivacyLink }}
|
||||||
{{end}}
|
<a
|
||||||
{{ if .HelpLink }}
|
href="{{.PrivacyLink}}"
|
||||||
<a href="{{.HelpLink}}" rel="noopener noreferrer" target="_blank" alt="Help">{{t "Footer.Help"}}</a>
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
alt="Privacy Policy"
|
||||||
|
>{{t "Footer.PrivacyPolicy"}}</a
|
||||||
|
>
|
||||||
|
{{end}} {{ if .HelpLink }}
|
||||||
|
<a href="{{.HelpLink}}" rel="noopener noreferrer" target="_blank" alt="Help"
|
||||||
|
>{{t "Footer.Help"}}</a
|
||||||
|
>
|
||||||
|
{{end}} {{ if .SupportEmail }}
|
||||||
|
<a
|
||||||
|
href="mailto:{{.SupportEmail}}"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
alt="Help"
|
||||||
|
>{{t "Footer.SupportEmail"}}</a
|
||||||
|
>
|
||||||
{{end}}
|
{{end}}
|
||||||
</footer>
|
</footer>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -1158,6 +1158,7 @@ func privacyPolicyToDomain(p *query.PrivacyPolicy) *domain.PrivacyPolicy {
|
|||||||
TOSLink: p.TOSLink,
|
TOSLink: p.TOSLink,
|
||||||
PrivacyLink: p.PrivacyLink,
|
PrivacyLink: p.PrivacyLink,
|
||||||
HelpLink: p.HelpLink,
|
HelpLink: p.HelpLink,
|
||||||
|
SupportEmail: p.SupportEmail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1093,6 +1093,10 @@ func (c *Commands) createFooterTextEvents(ctx context.Context, agg *eventstore.A
|
|||||||
if event != nil {
|
if event != nil {
|
||||||
events = append(events, event)
|
events = append(events, event)
|
||||||
}
|
}
|
||||||
|
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyFooterSupportEmail, existingText.FooterSupportEmail, text.Footer.SupportEmail, text.Language, defaultText)
|
||||||
|
if event != nil {
|
||||||
|
events = append(events, event)
|
||||||
|
}
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ type CustomLoginTextReadModel struct {
|
|||||||
FooterTOS string
|
FooterTOS string
|
||||||
FooterPrivacyPolicy string
|
FooterPrivacyPolicy string
|
||||||
FooterHelp string
|
FooterHelp string
|
||||||
FooterHelpLink string
|
FooterSupportEmail string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *CustomLoginTextReadModel) Reduce() error {
|
func (wm *CustomLoginTextReadModel) Reduce() error {
|
||||||
@ -2515,6 +2515,10 @@ func (wm *CustomLoginTextReadModel) handleFooterTextSetEvent(e *policy.CustomTex
|
|||||||
wm.FooterHelp = e.Text
|
wm.FooterHelp = e.Text
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if e.Key == domain.LoginKeyFooterSupportEmail {
|
||||||
|
wm.FooterSupportEmail = e.Text
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.CustomTextRemovedEvent) {
|
func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.CustomTextRemovedEvent) {
|
||||||
@ -2530,4 +2534,8 @@ func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.Custom
|
|||||||
wm.FooterHelp = ""
|
wm.FooterHelp = ""
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if e.Key == domain.LoginKeyFooterSupportEmail {
|
||||||
|
wm.FooterSupportEmail = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ type InstanceSetup struct {
|
|||||||
TOSLink string
|
TOSLink string
|
||||||
PrivacyLink string
|
PrivacyLink string
|
||||||
HelpLink string
|
HelpLink string
|
||||||
|
SupportEmail domain.EmailAddress
|
||||||
}
|
}
|
||||||
LabelPolicy struct {
|
LabelPolicy struct {
|
||||||
PrimaryColor string
|
PrimaryColor string
|
||||||
@ -242,7 +243,7 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
|||||||
prepareAddSecondFactorToDefaultLoginPolicy(instanceAgg, domain.SecondFactorTypeU2F),
|
prepareAddSecondFactorToDefaultLoginPolicy(instanceAgg, domain.SecondFactorTypeU2F),
|
||||||
prepareAddMultiFactorToDefaultLoginPolicy(instanceAgg, domain.MultiFactorTypeU2FWithPIN),
|
prepareAddMultiFactorToDefaultLoginPolicy(instanceAgg, domain.MultiFactorTypeU2FWithPIN),
|
||||||
|
|
||||||
prepareAddDefaultPrivacyPolicy(instanceAgg, setup.PrivacyPolicy.TOSLink, setup.PrivacyPolicy.PrivacyLink, setup.PrivacyPolicy.HelpLink),
|
prepareAddDefaultPrivacyPolicy(instanceAgg, setup.PrivacyPolicy.TOSLink, setup.PrivacyPolicy.PrivacyLink, setup.PrivacyPolicy.HelpLink, setup.PrivacyPolicy.SupportEmail),
|
||||||
prepareAddDefaultNotificationPolicy(instanceAgg, setup.NotificationPolicy.PasswordChange),
|
prepareAddDefaultNotificationPolicy(instanceAgg, setup.NotificationPolicy.PasswordChange),
|
||||||
prepareAddDefaultLockoutPolicy(instanceAgg, setup.LockoutPolicy.MaxAttempts, setup.LockoutPolicy.ShouldShowLockoutFailure),
|
prepareAddDefaultLockoutPolicy(instanceAgg, setup.LockoutPolicy.MaxAttempts, setup.LockoutPolicy.ShouldShowLockoutFailure),
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ func writeModelToPrivacyPolicy(wm *PrivacyPolicyWriteModel) *domain.PrivacyPolic
|
|||||||
TOSLink: wm.TOSLink,
|
TOSLink: wm.TOSLink,
|
||||||
PrivacyLink: wm.PrivacyLink,
|
PrivacyLink: wm.PrivacyLink,
|
||||||
HelpLink: wm.HelpLink,
|
HelpLink: wm.HelpLink,
|
||||||
|
SupportEmail: wm.SupportEmail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ func (c *Commands) setCustomInstanceLoginText(ctx context.Context, instanceAgg *
|
|||||||
if !text.IsValid() {
|
if !text.IsValid() {
|
||||||
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "Instance-kd9fs", "Errors.CustomText.Invalid")
|
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "Instance-kd9fs", "Errors.CustomText.Invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
existingLoginText, err := c.defaultLoginTextWriteModelByID(ctx, text.Language)
|
existingLoginText, err := c.defaultLoginTextWriteModelByID(ctx, text.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -1370,6 +1370,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1664,6 +1670,7 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
TOS: "TOS",
|
TOS: "TOS",
|
||||||
PrivacyPolicy: "PrivacyPolicy",
|
PrivacyPolicy: "PrivacyPolicy",
|
||||||
Help: "Help",
|
Help: "Help",
|
||||||
|
SupportEmail: "Support Email",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2993,6 +3000,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -4310,6 +4323,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewCustomTextRemovedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -5681,6 +5700,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
eventFromEventPusherWithInstanceID(
|
eventFromEventPusherWithInstanceID(
|
||||||
"INSTANCE",
|
"INSTANCE",
|
||||||
instance.NewCustomTextRemovedEvent(context.Background(),
|
instance.NewCustomTextRemovedEvent(context.Background(),
|
||||||
@ -6996,6 +7021,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewCustomTextRemovedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -8313,6 +8344,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -8607,6 +8644,7 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
|||||||
TOS: "TOS",
|
TOS: "TOS",
|
||||||
PrivacyPolicy: "PrivacyPolicy",
|
PrivacyPolicy: "PrivacyPolicy",
|
||||||
Help: "Help",
|
Help: "Help",
|
||||||
|
SupportEmail: "Support Email",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -12,9 +12,9 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddDefaultPrivacyPolicy(ctx context.Context, tosLink, privacyLink, helpLink string) (*domain.ObjectDetails, error) {
|
func (c *Commands) AddDefaultPrivacyPolicy(ctx context.Context, tosLink, privacyLink, helpLink string, supportEmail domain.EmailAddress) (*domain.ObjectDetails, error) {
|
||||||
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, prepareAddDefaultPrivacyPolicy(instanceAgg, tosLink, privacyLink, helpLink))
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, prepareAddDefaultPrivacyPolicy(instanceAgg, tosLink, privacyLink, helpLink, supportEmail))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -26,6 +26,13 @@ func (c *Commands) AddDefaultPrivacyPolicy(ctx context.Context, tosLink, privacy
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeDefaultPrivacyPolicy(ctx context.Context, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
func (c *Commands) ChangeDefaultPrivacyPolicy(ctx context.Context, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
||||||
|
if policy.SupportEmail != "" {
|
||||||
|
if err := policy.SupportEmail.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
policy.SupportEmail = policy.SupportEmail.Normalize()
|
||||||
|
}
|
||||||
|
|
||||||
existingPolicy, err := c.defaultPrivacyPolicyWriteModelByID(ctx)
|
existingPolicy, err := c.defaultPrivacyPolicyWriteModelByID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -35,7 +42,7 @@ func (c *Commands) ChangeDefaultPrivacyPolicy(ctx context.Context, policy *domai
|
|||||||
}
|
}
|
||||||
|
|
||||||
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.PrivacyPolicyWriteModel.WriteModel)
|
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.PrivacyPolicyWriteModel.WriteModel)
|
||||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, instanceAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink)
|
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, instanceAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink, policy.SupportEmail)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "INSTANCE-9jJfs", "Errors.IAM.PrivacyPolicy.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "INSTANCE-9jJfs", "Errors.IAM.PrivacyPolicy.NotChanged")
|
||||||
}
|
}
|
||||||
@ -81,8 +88,15 @@ func prepareAddDefaultPrivacyPolicy(
|
|||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink string,
|
helpLink string,
|
||||||
|
supportEmail domain.EmailAddress,
|
||||||
) preparation.Validation {
|
) preparation.Validation {
|
||||||
return func() (preparation.CreateCommands, error) {
|
return func() (preparation.CreateCommands, error) {
|
||||||
|
if supportEmail != "" {
|
||||||
|
if err := supportEmail.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
supportEmail = supportEmail.Normalize()
|
||||||
|
}
|
||||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
writeModel := NewInstancePrivacyPolicyWriteModel(ctx)
|
writeModel := NewInstancePrivacyPolicyWriteModel(ctx)
|
||||||
events, err := filter(ctx, writeModel.Query())
|
events, err := filter(ctx, writeModel.Query())
|
||||||
@ -97,7 +111,7 @@ func prepareAddDefaultPrivacyPolicy(
|
|||||||
return nil, caos_errs.ThrowAlreadyExists(nil, "INSTANCE-M00rJ", "Errors.Instance.PrivacyPolicy.AlreadyExists")
|
return nil, caos_errs.ThrowAlreadyExists(nil, "INSTANCE-M00rJ", "Errors.Instance.PrivacyPolicy.AlreadyExists")
|
||||||
}
|
}
|
||||||
return []eventstore.Command{
|
return []eventstore.Command{
|
||||||
instance.NewPrivacyPolicyAddedEvent(ctx, &a.Aggregate, tosLink, privacyLink, helpLink),
|
instance.NewPrivacyPolicyAddedEvent(ctx, &a.Aggregate, tosLink, privacyLink, helpLink, supportEmail),
|
||||||
}, nil
|
}, nil
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||||
@ -57,6 +58,7 @@ func (wm *InstancePrivacyPolicyWriteModel) NewChangedEvent(
|
|||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink string,
|
helpLink string,
|
||||||
|
supportEmail domain.EmailAddress,
|
||||||
) (*instance.PrivacyPolicyChangedEvent, bool) {
|
) (*instance.PrivacyPolicyChangedEvent, bool) {
|
||||||
|
|
||||||
changes := make([]policy.PrivacyPolicyChanges, 0)
|
changes := make([]policy.PrivacyPolicyChanges, 0)
|
||||||
@ -69,6 +71,9 @@ func (wm *InstancePrivacyPolicyWriteModel) NewChangedEvent(
|
|||||||
if wm.HelpLink != helpLink {
|
if wm.HelpLink != helpLink {
|
||||||
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
||||||
}
|
}
|
||||||
|
if wm.SupportEmail != supportEmail {
|
||||||
|
changes = append(changes, policy.ChangeSupportEmail(supportEmail))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
tosLink string
|
tosLink string
|
||||||
privacyLink string
|
privacyLink string
|
||||||
helpLink string
|
helpLink string
|
||||||
|
supportEmail domain.EmailAddress
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.ObjectDetails
|
want *domain.ObjectDetails
|
||||||
@ -49,6 +50,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -59,6 +61,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
tosLink: "TOSLink",
|
tosLink: "TOSLink",
|
||||||
privacyLink: "PrivacyLink",
|
privacyLink: "PrivacyLink",
|
||||||
helpLink: "HelpLink",
|
helpLink: "HelpLink",
|
||||||
|
supportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsErrorAlreadyExists,
|
err: caos_errs.IsErrorAlreadyExists,
|
||||||
@ -79,6 +82,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -90,6 +94,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
tosLink: "TOSLink",
|
tosLink: "TOSLink",
|
||||||
privacyLink: "PrivacyLink",
|
privacyLink: "PrivacyLink",
|
||||||
helpLink: "HelpLink",
|
helpLink: "HelpLink",
|
||||||
|
supportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.ObjectDetails{
|
want: &domain.ObjectDetails{
|
||||||
@ -97,6 +102,24 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "wrong email, can't add policy",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
|
tosLink: "TOSLink",
|
||||||
|
privacyLink: "PrivacyLink",
|
||||||
|
helpLink: "HelpLink",
|
||||||
|
supportEmail: "wrong email",
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "add empty policy,ok",
|
name: "add empty policy,ok",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@ -112,6 +135,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -123,6 +147,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
tosLink: "",
|
tosLink: "",
|
||||||
privacyLink: "",
|
privacyLink: "",
|
||||||
helpLink: "",
|
helpLink: "",
|
||||||
|
supportEmail: "",
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.ObjectDetails{
|
want: &domain.ObjectDetails{
|
||||||
@ -136,7 +161,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
got, err := r.AddDefaultPrivacyPolicy(tt.args.ctx, tt.args.tosLink, tt.args.privacyLink, tt.args.helpLink)
|
got, err := r.AddDefaultPrivacyPolicy(tt.args.ctx, tt.args.tosLink, tt.args.privacyLink, tt.args.helpLink, tt.args.supportEmail)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -182,6 +207,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -200,6 +226,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -211,12 +238,33 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsPreconditionFailed,
|
err: caos_errs.IsPreconditionFailed,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "wrong email, can't change policy",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
policy: &domain.PrivacyPolicy{
|
||||||
|
TOSLink: "TOSLink",
|
||||||
|
PrivacyLink: "PrivacyLink",
|
||||||
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "wrong email",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "change, ok",
|
name: "change, ok",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@ -229,6 +277,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -239,6 +288,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLinkChanged",
|
"TOSLinkChanged",
|
||||||
"PrivacyLinkChanged",
|
"PrivacyLinkChanged",
|
||||||
"HelpLinkChanged",
|
"HelpLinkChanged",
|
||||||
|
"support2@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -251,6 +301,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLinkChanged",
|
TOSLink: "TOSLinkChanged",
|
||||||
PrivacyLink: "PrivacyLinkChanged",
|
PrivacyLink: "PrivacyLinkChanged",
|
||||||
HelpLink: "HelpLinkChanged",
|
HelpLink: "HelpLinkChanged",
|
||||||
|
SupportEmail: "support2@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -262,6 +313,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLinkChanged",
|
TOSLink: "TOSLinkChanged",
|
||||||
PrivacyLink: "PrivacyLinkChanged",
|
PrivacyLink: "PrivacyLinkChanged",
|
||||||
HelpLink: "HelpLinkChanged",
|
HelpLink: "HelpLinkChanged",
|
||||||
|
SupportEmail: "support2@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -285,13 +337,14 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDefaultPrivacyPolicyChangedEvent(ctx context.Context, tosLink, privacyLink, helpLink string) *instance.PrivacyPolicyChangedEvent {
|
func newDefaultPrivacyPolicyChangedEvent(ctx context.Context, tosLink, privacyLink, helpLink, supportEmail string) *instance.PrivacyPolicyChangedEvent {
|
||||||
event, _ := instance.NewPrivacyPolicyChangedEvent(ctx,
|
event, _ := instance.NewPrivacyPolicyChangedEvent(ctx,
|
||||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
[]policy.PrivacyPolicyChanges{
|
[]policy.PrivacyPolicyChanges{
|
||||||
policy.ChangeTOSLink(tosLink),
|
policy.ChangeTOSLink(tosLink),
|
||||||
policy.ChangePrivacyLink(privacyLink),
|
policy.ChangePrivacyLink(privacyLink),
|
||||||
policy.ChangeHelpLink(helpLink),
|
policy.ChangeHelpLink(helpLink),
|
||||||
|
policy.ChangeSupportEmail(domain.EmailAddress(supportEmail)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return event
|
return event
|
||||||
|
@ -50,5 +50,6 @@ func orgWriteModelToPrivacyPolicy(wm *OrgPrivacyPolicyWriteModel) *domain.Privac
|
|||||||
TOSLink: wm.TOSLink,
|
TOSLink: wm.TOSLink,
|
||||||
PrivacyLink: wm.PrivacyLink,
|
PrivacyLink: wm.PrivacyLink,
|
||||||
HelpLink: wm.HelpLink,
|
HelpLink: wm.HelpLink,
|
||||||
|
SupportEmail: wm.SupportEmail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1161,6 +1161,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1455,6 +1460,7 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
TOS: "TOS",
|
TOS: "TOS",
|
||||||
PrivacyPolicy: "PrivacyPolicy",
|
PrivacyPolicy: "PrivacyPolicy",
|
||||||
Help: "Help",
|
Help: "Help",
|
||||||
|
SupportEmail: "Support Email",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2560,6 +2566,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -3653,6 +3664,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextRemovedEvent(context.Background(),
|
||||||
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -4800,6 +4816,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewCustomTextRemovedEvent(context.Background(),
|
org.NewCustomTextRemovedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeySelectAccountTitle, language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeySelectAccountTitle, language.English,
|
||||||
@ -5890,6 +5911,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextRemovedEvent(context.Background(),
|
||||||
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -6983,6 +7009,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewCustomTextSetEvent(context.Background(),
|
||||||
|
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -7277,6 +7308,7 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
|||||||
TOS: "TOS",
|
TOS: "TOS",
|
||||||
PrivacyPolicy: "PrivacyPolicy",
|
PrivacyPolicy: "PrivacyPolicy",
|
||||||
Help: "Help",
|
Help: "Help",
|
||||||
|
SupportEmail: "Support Email",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -29,6 +29,14 @@ func (c *Commands) orgPrivacyPolicyWriteModelByID(ctx context.Context, orgID str
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) AddPrivacyPolicy(ctx context.Context, resourceOwner string, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
func (c *Commands) AddPrivacyPolicy(ctx context.Context, resourceOwner string, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
||||||
|
|
||||||
|
if policy.SupportEmail != "" {
|
||||||
|
if err := policy.SupportEmail.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
policy.SupportEmail = policy.SupportEmail.Normalize()
|
||||||
|
}
|
||||||
|
|
||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-MMk9fs", "Errors.ResourceOwnerMissing")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-MMk9fs", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
@ -49,7 +57,8 @@ func (c *Commands) AddPrivacyPolicy(ctx context.Context, resourceOwner string, p
|
|||||||
orgAgg,
|
orgAgg,
|
||||||
policy.TOSLink,
|
policy.TOSLink,
|
||||||
policy.PrivacyLink,
|
policy.PrivacyLink,
|
||||||
policy.HelpLink))
|
policy.HelpLink,
|
||||||
|
policy.SupportEmail))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -61,12 +70,19 @@ func (c *Commands) AddPrivacyPolicy(ctx context.Context, resourceOwner string, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangePrivacyPolicy(ctx context.Context, resourceOwner string, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
func (c *Commands) ChangePrivacyPolicy(ctx context.Context, resourceOwner string, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
||||||
|
|
||||||
|
if policy.SupportEmail != "" {
|
||||||
|
if err := policy.SupportEmail.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
policy.SupportEmail = policy.SupportEmail.Normalize()
|
||||||
|
}
|
||||||
|
|
||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-22N89f", "Errors.ResourceOwnerMissing")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-22N89f", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
|
|
||||||
existingPolicy := NewOrgPrivacyPolicyWriteModel(resourceOwner)
|
existingPolicy, err := c.orgPrivacyPolicyWriteModelByID(ctx, resourceOwner)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -75,7 +91,7 @@ func (c *Commands) ChangePrivacyPolicy(ctx context.Context, resourceOwner string
|
|||||||
}
|
}
|
||||||
|
|
||||||
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PrivacyPolicyWriteModel.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PrivacyPolicyWriteModel.WriteModel)
|
||||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink)
|
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink, policy.SupportEmail)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4N9fs", "Errors.Org.PrivacyPolicy.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4N9fs", "Errors.Org.PrivacyPolicy.NotChanged")
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package command
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
@ -59,6 +59,7 @@ func (wm *OrgPrivacyPolicyWriteModel) NewChangedEvent(
|
|||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink string,
|
helpLink string,
|
||||||
|
supportEmail domain.EmailAddress,
|
||||||
) (*org.PrivacyPolicyChangedEvent, bool) {
|
) (*org.PrivacyPolicyChangedEvent, bool) {
|
||||||
|
|
||||||
changes := make([]policy.PrivacyPolicyChanges, 0)
|
changes := make([]policy.PrivacyPolicyChanges, 0)
|
||||||
@ -71,6 +72,9 @@ func (wm *OrgPrivacyPolicyWriteModel) NewChangedEvent(
|
|||||||
if wm.HelpLink != helpLink {
|
if wm.HelpLink != helpLink {
|
||||||
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
||||||
}
|
}
|
||||||
|
if wm.SupportEmail != supportEmail {
|
||||||
|
changes = append(changes, policy.ChangeSupportEmail(supportEmail))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -65,6 +66,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -77,6 +79,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -97,6 +100,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -110,6 +114,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -121,11 +126,33 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "add policy empty links, ok",
|
name: "wrong email, can't add policy",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
orgID: "org1",
|
||||||
|
policy: &domain.PrivacyPolicy{
|
||||||
|
TOSLink: "TOSLink",
|
||||||
|
PrivacyLink: "PrivacyLink",
|
||||||
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "wrong email",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "add policy empty links and empty support email, ok",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
eventstore: eventstoreExpect(
|
eventstore: eventstoreExpect(
|
||||||
t,
|
t,
|
||||||
@ -138,6 +165,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -151,6 +179,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "",
|
TOSLink: "",
|
||||||
PrivacyLink: "",
|
PrivacyLink: "",
|
||||||
HelpLink: "",
|
HelpLink: "",
|
||||||
|
SupportEmail: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -162,6 +191,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "",
|
TOSLink: "",
|
||||||
PrivacyLink: "",
|
PrivacyLink: "",
|
||||||
HelpLink: "",
|
HelpLink: "",
|
||||||
|
SupportEmail: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -217,6 +247,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -238,6 +269,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -256,6 +288,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -268,12 +301,29 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLink",
|
TOSLink: "TOSLink",
|
||||||
PrivacyLink: "PrivacyLink",
|
PrivacyLink: "PrivacyLink",
|
||||||
HelpLink: "HelpLink",
|
HelpLink: "HelpLink",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsPreconditionFailed,
|
err: caos_errs.IsPreconditionFailed,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "wrong email, can't change policy",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
orgID: "org1",
|
||||||
|
policy: &domain.PrivacyPolicy{
|
||||||
|
TOSLink: "TOSLinkChange",
|
||||||
|
PrivacyLink: "PrivacyLinkChange",
|
||||||
|
HelpLink: "HelpLinkChange",
|
||||||
|
SupportEmail: "wrong email",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "change, ok",
|
name: "change, ok",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@ -286,13 +336,14 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "TOSLinkChange", "PrivacyLinkChange", "HelpLinkChange"),
|
newPrivacyPolicyChangedEvent(context.Background(), "org1", "TOSLinkChange", "PrivacyLinkChange", "HelpLinkChange", "support2@example.com"),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -305,6 +356,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLinkChange",
|
TOSLink: "TOSLinkChange",
|
||||||
PrivacyLink: "PrivacyLinkChange",
|
PrivacyLink: "PrivacyLinkChange",
|
||||||
HelpLink: "HelpLinkChange",
|
HelpLink: "HelpLinkChange",
|
||||||
|
SupportEmail: "support2@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -316,6 +368,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "TOSLinkChange",
|
TOSLink: "TOSLinkChange",
|
||||||
PrivacyLink: "PrivacyLinkChange",
|
PrivacyLink: "PrivacyLinkChange",
|
||||||
HelpLink: "HelpLinkChange",
|
HelpLink: "HelpLinkChange",
|
||||||
|
SupportEmail: "support2@example.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -331,13 +384,14 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "", "", ""),
|
newPrivacyPolicyChangedEvent(context.Background(), "org1", "", "", "", ""),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -350,6 +404,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "",
|
TOSLink: "",
|
||||||
PrivacyLink: "",
|
PrivacyLink: "",
|
||||||
HelpLink: "",
|
HelpLink: "",
|
||||||
|
SupportEmail: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -361,6 +416,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
|||||||
TOSLink: "",
|
TOSLink: "",
|
||||||
PrivacyLink: "",
|
PrivacyLink: "",
|
||||||
HelpLink: "",
|
HelpLink: "",
|
||||||
|
SupportEmail: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -444,6 +500,7 @@ func TestCommandSide_RemovePrivacyPolicy(t *testing.T) {
|
|||||||
"TOSLink",
|
"TOSLink",
|
||||||
"PrivacyLink",
|
"PrivacyLink",
|
||||||
"HelpLink",
|
"HelpLink",
|
||||||
|
"support@example.com",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -487,13 +544,14 @@ func TestCommandSide_RemovePrivacyPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPrivacyPolicyChangedEvent(ctx context.Context, orgID string, tosLink, privacyLink, helpLink string) *org.PrivacyPolicyChangedEvent {
|
func newPrivacyPolicyChangedEvent(ctx context.Context, orgID string, tosLink, privacyLink, helpLink, supportEmail string) *org.PrivacyPolicyChangedEvent {
|
||||||
event, _ := org.NewPrivacyPolicyChangedEvent(ctx,
|
event, _ := org.NewPrivacyPolicyChangedEvent(ctx,
|
||||||
&org.NewAggregate(orgID).Aggregate,
|
&org.NewAggregate(orgID).Aggregate,
|
||||||
[]policy.PrivacyPolicyChanges{
|
[]policy.PrivacyPolicyChanges{
|
||||||
policy.ChangeTOSLink(tosLink),
|
policy.ChangeTOSLink(tosLink),
|
||||||
policy.ChangePrivacyLink(privacyLink),
|
policy.ChangePrivacyLink(privacyLink),
|
||||||
policy.ChangeHelpLink(helpLink),
|
policy.ChangeHelpLink(helpLink),
|
||||||
|
policy.ChangeSupportEmail(domain.EmailAddress(supportEmail)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return event
|
return event
|
||||||
|
@ -12,6 +12,7 @@ type PrivacyPolicyWriteModel struct {
|
|||||||
TOSLink string
|
TOSLink string
|
||||||
PrivacyLink string
|
PrivacyLink string
|
||||||
HelpLink string
|
HelpLink string
|
||||||
|
SupportEmail domain.EmailAddress
|
||||||
State domain.PolicyState
|
State domain.PolicyState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
|||||||
wm.TOSLink = e.TOSLink
|
wm.TOSLink = e.TOSLink
|
||||||
wm.PrivacyLink = e.PrivacyLink
|
wm.PrivacyLink = e.PrivacyLink
|
||||||
wm.HelpLink = e.HelpLink
|
wm.HelpLink = e.HelpLink
|
||||||
|
wm.SupportEmail = e.SupportEmail
|
||||||
wm.State = domain.PolicyStateActive
|
wm.State = domain.PolicyStateActive
|
||||||
case *policy.PrivacyPolicyChangedEvent:
|
case *policy.PrivacyPolicyChangedEvent:
|
||||||
if e.PrivacyLink != nil {
|
if e.PrivacyLink != nil {
|
||||||
@ -33,6 +35,9 @@ func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
|||||||
if e.HelpLink != nil {
|
if e.HelpLink != nil {
|
||||||
wm.HelpLink = *e.HelpLink
|
wm.HelpLink = *e.HelpLink
|
||||||
}
|
}
|
||||||
|
if e.SupportEmail != nil {
|
||||||
|
wm.SupportEmail = *e.SupportEmail
|
||||||
|
}
|
||||||
case *policy.PrivacyPolicyRemovedEvent:
|
case *policy.PrivacyPolicyRemovedEvent:
|
||||||
wm.State = domain.PolicyStateRemoved
|
wm.State = domain.PolicyStateRemoved
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,7 @@ const (
|
|||||||
LoginKeyFooterTOS = LoginKeyFooter + "Tos"
|
LoginKeyFooterTOS = LoginKeyFooter + "Tos"
|
||||||
LoginKeyFooterPrivacyPolicy = LoginKeyFooter + "PrivacyPolicy"
|
LoginKeyFooterPrivacyPolicy = LoginKeyFooter + "PrivacyPolicy"
|
||||||
LoginKeyFooterHelp = LoginKeyFooter + "Help"
|
LoginKeyFooterHelp = LoginKeyFooter + "Help"
|
||||||
|
LoginKeyFooterSupportEmail = LoginKeyFooter + "SupportEmail"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CustomLoginText struct {
|
type CustomLoginText struct {
|
||||||
@ -639,6 +640,7 @@ type FooterText struct {
|
|||||||
TOS string
|
TOS string
|
||||||
PrivacyPolicy string
|
PrivacyPolicy string
|
||||||
Help string
|
Help string
|
||||||
|
SupportEmail string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordlessPromptScreenText struct {
|
type PasswordlessPromptScreenText struct {
|
||||||
|
@ -13,4 +13,5 @@ type PrivacyPolicy struct {
|
|||||||
TOSLink string
|
TOSLink string
|
||||||
PrivacyLink string
|
PrivacyLink string
|
||||||
HelpLink string
|
HelpLink string
|
||||||
|
SupportEmail EmailAddress
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ type PrivacyPolicyView struct {
|
|||||||
AggregateID string
|
AggregateID string
|
||||||
TOSLink string
|
TOSLink string
|
||||||
PrivacyLink string
|
PrivacyLink string
|
||||||
|
SupportEmail string
|
||||||
Default bool
|
Default bool
|
||||||
|
|
||||||
CreationDate time.Time
|
CreationDate time.Time
|
||||||
|
@ -1181,4 +1181,7 @@ func footerKeyToDomain(text *CustomText, result *domain.CustomLoginText) {
|
|||||||
if text.Key == domain.LoginKeyFooterHelp {
|
if text.Key == domain.LoginKeyFooterHelp {
|
||||||
result.Footer.Help = text.Text
|
result.Footer.Help = text.Text
|
||||||
}
|
}
|
||||||
|
if text.Key == domain.LoginKeyFooterSupportEmail {
|
||||||
|
result.Footer.SupportEmail = text.Text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ type PrivacyPolicy struct {
|
|||||||
TOSLink string
|
TOSLink string
|
||||||
PrivacyLink string
|
PrivacyLink string
|
||||||
HelpLink string
|
HelpLink string
|
||||||
|
SupportEmail domain.EmailAddress
|
||||||
|
|
||||||
IsDefault bool
|
IsDefault bool
|
||||||
}
|
}
|
||||||
@ -72,6 +73,10 @@ var (
|
|||||||
name: projection.PrivacyPolicyHelpLinkCol,
|
name: projection.PrivacyPolicyHelpLinkCol,
|
||||||
table: privacyTable,
|
table: privacyTable,
|
||||||
}
|
}
|
||||||
|
PrivacyColSupportEmail = Column{
|
||||||
|
name: projection.PrivacyPolicySupportEmailCol,
|
||||||
|
table: privacyTable,
|
||||||
|
}
|
||||||
PrivacyColIsDefault = Column{
|
PrivacyColIsDefault = Column{
|
||||||
name: projection.PrivacyPolicyIsDefaultCol,
|
name: projection.PrivacyPolicyIsDefaultCol,
|
||||||
table: privacyTable,
|
table: privacyTable,
|
||||||
@ -148,6 +153,7 @@ func preparePrivacyPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
|
|||||||
PrivacyColPrivacyLink.identifier(),
|
PrivacyColPrivacyLink.identifier(),
|
||||||
PrivacyColTOSLink.identifier(),
|
PrivacyColTOSLink.identifier(),
|
||||||
PrivacyColHelpLink.identifier(),
|
PrivacyColHelpLink.identifier(),
|
||||||
|
PrivacyColSupportEmail.identifier(),
|
||||||
PrivacyColIsDefault.identifier(),
|
PrivacyColIsDefault.identifier(),
|
||||||
PrivacyColState.identifier(),
|
PrivacyColState.identifier(),
|
||||||
).
|
).
|
||||||
@ -164,6 +170,7 @@ func preparePrivacyPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
|
|||||||
&policy.PrivacyLink,
|
&policy.PrivacyLink,
|
||||||
&policy.TOSLink,
|
&policy.TOSLink,
|
||||||
&policy.HelpLink,
|
&policy.HelpLink,
|
||||||
|
&policy.SupportEmail,
|
||||||
&policy.IsDefault,
|
&policy.IsDefault,
|
||||||
&policy.State,
|
&policy.State,
|
||||||
)
|
)
|
||||||
@ -182,6 +189,7 @@ func (p *PrivacyPolicy) ToDomain() *domain.PrivacyPolicy {
|
|||||||
TOSLink: p.TOSLink,
|
TOSLink: p.TOSLink,
|
||||||
PrivacyLink: p.PrivacyLink,
|
PrivacyLink: p.PrivacyLink,
|
||||||
HelpLink: p.HelpLink,
|
HelpLink: p.HelpLink,
|
||||||
|
SupportEmail: p.SupportEmail,
|
||||||
Default: p.IsDefault,
|
Default: p.IsDefault,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
preparePrivacyPolicyStmt = `SELECT projections.privacy_policies2.id,` +
|
preparePrivacyPolicyStmt = `SELECT projections.privacy_policies3.id,` +
|
||||||
` projections.privacy_policies2.sequence,` +
|
` projections.privacy_policies3.sequence,` +
|
||||||
` projections.privacy_policies2.creation_date,` +
|
` projections.privacy_policies3.creation_date,` +
|
||||||
` projections.privacy_policies2.change_date,` +
|
` projections.privacy_policies3.change_date,` +
|
||||||
` projections.privacy_policies2.resource_owner,` +
|
` projections.privacy_policies3.resource_owner,` +
|
||||||
` projections.privacy_policies2.privacy_link,` +
|
` projections.privacy_policies3.privacy_link,` +
|
||||||
` projections.privacy_policies2.tos_link,` +
|
` projections.privacy_policies3.tos_link,` +
|
||||||
` projections.privacy_policies2.help_link,` +
|
` projections.privacy_policies3.help_link,` +
|
||||||
` projections.privacy_policies2.is_default,` +
|
` projections.privacy_policies3.support_email,` +
|
||||||
` projections.privacy_policies2.state` +
|
` projections.privacy_policies3.is_default,` +
|
||||||
` FROM projections.privacy_policies2` +
|
` projections.privacy_policies3.state` +
|
||||||
|
` FROM projections.privacy_policies3` +
|
||||||
` AS OF SYSTEM TIME '-1 ms'`
|
` AS OF SYSTEM TIME '-1 ms'`
|
||||||
preparePrivacyPolicyCols = []string{
|
preparePrivacyPolicyCols = []string{
|
||||||
"id",
|
"id",
|
||||||
@ -34,6 +35,7 @@ var (
|
|||||||
"privacy_link",
|
"privacy_link",
|
||||||
"tos_link",
|
"tos_link",
|
||||||
"help_link",
|
"help_link",
|
||||||
|
"support_email",
|
||||||
"is_default",
|
"is_default",
|
||||||
"state",
|
"state",
|
||||||
}
|
}
|
||||||
@ -84,6 +86,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
|||||||
"privacy.ch",
|
"privacy.ch",
|
||||||
"tos.ch",
|
"tos.ch",
|
||||||
"help.ch",
|
"help.ch",
|
||||||
|
"support@example.com",
|
||||||
true,
|
true,
|
||||||
domain.PolicyStateActive,
|
domain.PolicyStateActive,
|
||||||
},
|
},
|
||||||
@ -99,6 +102,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
|||||||
PrivacyLink: "privacy.ch",
|
PrivacyLink: "privacy.ch",
|
||||||
TOSLink: "tos.ch",
|
TOSLink: "tos.ch",
|
||||||
HelpLink: "help.ch",
|
HelpLink: "help.ch",
|
||||||
|
SupportEmail: "support@example.com",
|
||||||
IsDefault: true,
|
IsDefault: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PrivacyPolicyTable = "projections.privacy_policies2"
|
PrivacyPolicyTable = "projections.privacy_policies3"
|
||||||
|
|
||||||
PrivacyPolicyIDCol = "id"
|
PrivacyPolicyIDCol = "id"
|
||||||
PrivacyPolicyCreationDateCol = "creation_date"
|
PrivacyPolicyCreationDateCol = "creation_date"
|
||||||
@ -27,6 +27,7 @@ const (
|
|||||||
PrivacyPolicyPrivacyLinkCol = "privacy_link"
|
PrivacyPolicyPrivacyLinkCol = "privacy_link"
|
||||||
PrivacyPolicyTOSLinkCol = "tos_link"
|
PrivacyPolicyTOSLinkCol = "tos_link"
|
||||||
PrivacyPolicyHelpLinkCol = "help_link"
|
PrivacyPolicyHelpLinkCol = "help_link"
|
||||||
|
PrivacyPolicySupportEmailCol = "support_email"
|
||||||
PrivacyPolicyOwnerRemovedCol = "owner_removed"
|
PrivacyPolicyOwnerRemovedCol = "owner_removed"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,6 +52,7 @@ func newPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandle
|
|||||||
crdb.NewColumn(PrivacyPolicyPrivacyLinkCol, crdb.ColumnTypeText),
|
crdb.NewColumn(PrivacyPolicyPrivacyLinkCol, crdb.ColumnTypeText),
|
||||||
crdb.NewColumn(PrivacyPolicyTOSLinkCol, crdb.ColumnTypeText),
|
crdb.NewColumn(PrivacyPolicyTOSLinkCol, crdb.ColumnTypeText),
|
||||||
crdb.NewColumn(PrivacyPolicyHelpLinkCol, crdb.ColumnTypeText),
|
crdb.NewColumn(PrivacyPolicyHelpLinkCol, crdb.ColumnTypeText),
|
||||||
|
crdb.NewColumn(PrivacyPolicySupportEmailCol, crdb.ColumnTypeText),
|
||||||
crdb.NewColumn(PrivacyPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
|
crdb.NewColumn(PrivacyPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
|
||||||
},
|
},
|
||||||
crdb.NewPrimaryKey(PrivacyPolicyInstanceIDCol, PrivacyPolicyIDCol),
|
crdb.NewPrimaryKey(PrivacyPolicyInstanceIDCol, PrivacyPolicyIDCol),
|
||||||
@ -128,6 +130,7 @@ func (p *privacyPolicyProjection) reduceAdded(event eventstore.Event) (*handler.
|
|||||||
handler.NewCol(PrivacyPolicyPrivacyLinkCol, policyEvent.PrivacyLink),
|
handler.NewCol(PrivacyPolicyPrivacyLinkCol, policyEvent.PrivacyLink),
|
||||||
handler.NewCol(PrivacyPolicyTOSLinkCol, policyEvent.TOSLink),
|
handler.NewCol(PrivacyPolicyTOSLinkCol, policyEvent.TOSLink),
|
||||||
handler.NewCol(PrivacyPolicyHelpLinkCol, policyEvent.HelpLink),
|
handler.NewCol(PrivacyPolicyHelpLinkCol, policyEvent.HelpLink),
|
||||||
|
handler.NewCol(PrivacyPolicySupportEmailCol, policyEvent.SupportEmail),
|
||||||
handler.NewCol(PrivacyPolicyIsDefaultCol, isDefault),
|
handler.NewCol(PrivacyPolicyIsDefaultCol, isDefault),
|
||||||
handler.NewCol(PrivacyPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner),
|
handler.NewCol(PrivacyPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner),
|
||||||
handler.NewCol(PrivacyPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
|
handler.NewCol(PrivacyPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
|
||||||
@ -157,6 +160,9 @@ func (p *privacyPolicyProjection) reduceChanged(event eventstore.Event) (*handle
|
|||||||
if policyEvent.HelpLink != nil {
|
if policyEvent.HelpLink != nil {
|
||||||
cols = append(cols, handler.NewCol(PrivacyPolicyHelpLinkCol, *policyEvent.HelpLink))
|
cols = append(cols, handler.NewCol(PrivacyPolicyHelpLinkCol, *policyEvent.HelpLink))
|
||||||
}
|
}
|
||||||
|
if policyEvent.SupportEmail != nil {
|
||||||
|
cols = append(cols, handler.NewCol(PrivacyPolicySupportEmailCol, *policyEvent.SupportEmail))
|
||||||
|
}
|
||||||
return crdb.NewUpdateStatement(
|
return crdb.NewUpdateStatement(
|
||||||
&policyEvent,
|
&policyEvent,
|
||||||
cols,
|
cols,
|
||||||
|
@ -31,8 +31,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"tosLink": "http://tos.link",
|
"tosLink": "http://tos.link",
|
||||||
"privacyLink": "http://privacy.link",
|
"privacyLink": "http://privacy.link",
|
||||||
"helpLink": "http://help.link"
|
"helpLink": "http://help.link",
|
||||||
}`),
|
"supportEmail": "support@example.com"}`),
|
||||||
), org.PrivacyPolicyAddedEventMapper),
|
), org.PrivacyPolicyAddedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: (&privacyPolicyProjection{}).reduceAdded,
|
reduce: (&privacyPolicyProjection{}).reduceAdded,
|
||||||
@ -43,7 +43,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.privacy_policies2 (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
expectedStmt: "INSERT INTO projections.privacy_policies3 (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, support_email, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -53,6 +53,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
"http://privacy.link",
|
"http://privacy.link",
|
||||||
"http://tos.link",
|
"http://tos.link",
|
||||||
"http://help.link",
|
"http://help.link",
|
||||||
|
domain.EmailAddress("support@example.com"),
|
||||||
false,
|
false,
|
||||||
"ro-id",
|
"ro-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -72,8 +73,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"tosLink": "http://tos.link",
|
"tosLink": "http://tos.link",
|
||||||
"privacyLink": "http://privacy.link",
|
"privacyLink": "http://privacy.link",
|
||||||
"helpLink": "http://help.link"
|
"helpLink": "http://help.link",
|
||||||
}`),
|
"supportEmail": "support@example.com"}`),
|
||||||
), org.PrivacyPolicyChangedEventMapper),
|
), org.PrivacyPolicyChangedEventMapper),
|
||||||
},
|
},
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -83,13 +84,14 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.privacy_policies2 SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
|
expectedStmt: "UPDATE projections.privacy_policies3 SET (change_date, sequence, privacy_link, tos_link, help_link, support_email) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (instance_id = $8)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
uint64(15),
|
uint64(15),
|
||||||
"http://privacy.link",
|
"http://privacy.link",
|
||||||
"http://tos.link",
|
"http://tos.link",
|
||||||
"http://help.link",
|
"http://help.link",
|
||||||
|
domain.EmailAddress("support@example.com"),
|
||||||
"agg-id",
|
"agg-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
},
|
},
|
||||||
@ -115,7 +117,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.privacy_policies2 WHERE (id = $1) AND (instance_id = $2)",
|
expectedStmt: "DELETE FROM projections.privacy_policies3 WHERE (id = $1) AND (instance_id = $2)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -141,7 +143,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.privacy_policies2 WHERE (instance_id = $1)",
|
expectedStmt: "DELETE FROM projections.privacy_policies3 WHERE (instance_id = $1)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
},
|
},
|
||||||
@ -160,8 +162,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"tosLink": "http://tos.link",
|
"tosLink": "http://tos.link",
|
||||||
"privacyLink": "http://privacy.link",
|
"privacyLink": "http://privacy.link",
|
||||||
"helpLink": "http://help.link"
|
"helpLink": "http://help.link",
|
||||||
}`),
|
"supportEmail": "support@example.com"}`),
|
||||||
), instance.PrivacyPolicyAddedEventMapper),
|
), instance.PrivacyPolicyAddedEventMapper),
|
||||||
},
|
},
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -171,7 +173,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.privacy_policies2 (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
expectedStmt: "INSERT INTO projections.privacy_policies3 (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, support_email, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -181,6 +183,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
"http://privacy.link",
|
"http://privacy.link",
|
||||||
"http://tos.link",
|
"http://tos.link",
|
||||||
"http://help.link",
|
"http://help.link",
|
||||||
|
domain.EmailAddress("support@example.com"),
|
||||||
true,
|
true,
|
||||||
"ro-id",
|
"ro-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -200,8 +203,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
[]byte(`{
|
[]byte(`{
|
||||||
"tosLink": "http://tos.link",
|
"tosLink": "http://tos.link",
|
||||||
"privacyLink": "http://privacy.link",
|
"privacyLink": "http://privacy.link",
|
||||||
"helpLink": "http://help.link"
|
"helpLink": "http://help.link",
|
||||||
}`),
|
"supportEmail": "support@example.com"}`),
|
||||||
), instance.PrivacyPolicyChangedEventMapper),
|
), instance.PrivacyPolicyChangedEventMapper),
|
||||||
},
|
},
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
@ -211,13 +214,14 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.privacy_policies2 SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
|
expectedStmt: "UPDATE projections.privacy_policies3 SET (change_date, sequence, privacy_link, tos_link, help_link, support_email) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (instance_id = $8)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
uint64(15),
|
uint64(15),
|
||||||
"http://privacy.link",
|
"http://privacy.link",
|
||||||
"http://tos.link",
|
"http://tos.link",
|
||||||
"http://help.link",
|
"http://help.link",
|
||||||
|
domain.EmailAddress("support@example.com"),
|
||||||
"agg-id",
|
"agg-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
},
|
},
|
||||||
@ -243,7 +247,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.privacy_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
|
expectedStmt: "UPDATE projections.privacy_policies3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
uint64(15),
|
uint64(15),
|
||||||
|
@ -3,8 +3,8 @@ package instance
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
@ -24,6 +24,7 @@ func NewPrivacyPolicyAddedEvent(
|
|||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink string,
|
helpLink string,
|
||||||
|
supportEmail domain.EmailAddress,
|
||||||
) *PrivacyPolicyAddedEvent {
|
) *PrivacyPolicyAddedEvent {
|
||||||
return &PrivacyPolicyAddedEvent{
|
return &PrivacyPolicyAddedEvent{
|
||||||
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
||||||
@ -33,7 +34,8 @@ func NewPrivacyPolicyAddedEvent(
|
|||||||
PrivacyPolicyAddedEventType),
|
PrivacyPolicyAddedEventType),
|
||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink),
|
helpLink,
|
||||||
|
supportEmail),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ package org
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
@ -25,6 +25,7 @@ func NewPrivacyPolicyAddedEvent(
|
|||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink string,
|
helpLink string,
|
||||||
|
supportEmail domain.EmailAddress,
|
||||||
) *PrivacyPolicyAddedEvent {
|
) *PrivacyPolicyAddedEvent {
|
||||||
return &PrivacyPolicyAddedEvent{
|
return &PrivacyPolicyAddedEvent{
|
||||||
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
||||||
@ -34,7 +35,8 @@ func NewPrivacyPolicyAddedEvent(
|
|||||||
PrivacyPolicyAddedEventType),
|
PrivacyPolicyAddedEventType),
|
||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink),
|
helpLink,
|
||||||
|
supportEmail),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package policy
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ type PrivacyPolicyAddedEvent struct {
|
|||||||
TOSLink string `json:"tosLink,omitempty"`
|
TOSLink string `json:"tosLink,omitempty"`
|
||||||
PrivacyLink string `json:"privacyLink,omitempty"`
|
PrivacyLink string `json:"privacyLink,omitempty"`
|
||||||
HelpLink string `json:"helpLink,omitempty"`
|
HelpLink string `json:"helpLink,omitempty"`
|
||||||
|
SupportEmail domain.EmailAddress `json:"supportEmail,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PrivacyPolicyAddedEvent) Data() interface{} {
|
func (e *PrivacyPolicyAddedEvent) Data() interface{} {
|
||||||
@ -36,12 +37,14 @@ func NewPrivacyPolicyAddedEvent(
|
|||||||
tosLink,
|
tosLink,
|
||||||
privacyLink,
|
privacyLink,
|
||||||
helpLink string,
|
helpLink string,
|
||||||
|
supportEmail domain.EmailAddress,
|
||||||
) *PrivacyPolicyAddedEvent {
|
) *PrivacyPolicyAddedEvent {
|
||||||
return &PrivacyPolicyAddedEvent{
|
return &PrivacyPolicyAddedEvent{
|
||||||
BaseEvent: *base,
|
BaseEvent: *base,
|
||||||
TOSLink: tosLink,
|
TOSLink: tosLink,
|
||||||
PrivacyLink: privacyLink,
|
PrivacyLink: privacyLink,
|
||||||
HelpLink: helpLink,
|
HelpLink: helpLink,
|
||||||
|
SupportEmail: supportEmail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +66,7 @@ type PrivacyPolicyChangedEvent struct {
|
|||||||
TOSLink *string `json:"tosLink,omitempty"`
|
TOSLink *string `json:"tosLink,omitempty"`
|
||||||
PrivacyLink *string `json:"privacyLink,omitempty"`
|
PrivacyLink *string `json:"privacyLink,omitempty"`
|
||||||
HelpLink *string `json:"helpLink,omitempty"`
|
HelpLink *string `json:"helpLink,omitempty"`
|
||||||
|
SupportEmail *domain.EmailAddress `json:"supportEmail,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PrivacyPolicyChangedEvent) Data() interface{} {
|
func (e *PrivacyPolicyChangedEvent) Data() interface{} {
|
||||||
@ -109,6 +113,12 @@ func ChangeHelpLink(helpLink string) func(*PrivacyPolicyChangedEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeSupportEmail(supportEmail domain.EmailAddress) func(*PrivacyPolicyChangedEvent) {
|
||||||
|
return func(e *PrivacyPolicyChangedEvent) {
|
||||||
|
e.SupportEmail = &supportEmail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func PrivacyPolicyChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
func PrivacyPolicyChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
e := &PrivacyPolicyChangedEvent{
|
e := &PrivacyPolicyChangedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
@ -5460,6 +5460,13 @@ message UpdatePrivacyPolicyRequest {
|
|||||||
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
string support_email = 4 [
|
||||||
|
(validate.rules).string = {ignore_empty: true, max_len: 320, email: true},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"support-email@test.com\"";
|
||||||
|
description: "help / support email address."
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdatePrivacyPolicyResponse {
|
message UpdatePrivacyPolicyResponse {
|
||||||
|
@ -9834,6 +9834,13 @@ message AddCustomPrivacyPolicyRequest {
|
|||||||
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
string support_email = 4 [
|
||||||
|
(validate.rules).string = {ignore_empty: true, max_len: 320, email: true},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"support-email@test.com\"";
|
||||||
|
description: "help / support email address."
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddCustomPrivacyPolicyResponse {
|
message AddCustomPrivacyPolicyResponse {
|
||||||
@ -9859,6 +9866,13 @@ message UpdateCustomPrivacyPolicyRequest {
|
|||||||
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
string support_email = 4 [
|
||||||
|
(validate.rules).string = {ignore_empty: true, max_len: 320, email: true},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"support-email@test.com\"";
|
||||||
|
description: "help / support email address."
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateCustomPrivacyPolicyResponse {
|
message UpdateCustomPrivacyPolicyResponse {
|
||||||
|
@ -4,6 +4,7 @@ import "zitadel/object.proto";
|
|||||||
import "zitadel/idp.proto";
|
import "zitadel/idp.proto";
|
||||||
import "google/protobuf/duration.proto";
|
import "google/protobuf/duration.proto";
|
||||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||||
|
import "validate/validate.proto";
|
||||||
|
|
||||||
package zitadel.policy.v1;
|
package zitadel.policy.v1;
|
||||||
|
|
||||||
@ -345,6 +346,13 @@ message PrivacyPolicy {
|
|||||||
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
string support_email = 6 [
|
||||||
|
(validate.rules).string = {ignore_empty: true, max_len: 320, email: true},
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
example: "\"support-email@test.com\"";
|
||||||
|
description: "help / support email address."
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
message NotificationPolicy {
|
message NotificationPolicy {
|
||||||
|
@ -394,11 +394,12 @@ message LogoutDoneScreenText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message FooterText {
|
message FooterText {
|
||||||
reserved 2, 4, 6;
|
reserved 2, 4, 6, 8;
|
||||||
reserved "tos_link", "privacy_policy_link", "help_link";
|
reserved "tos_link", "privacy_policy_link", "help_link";
|
||||||
string tos = 1 [(validate.rules).string = {max_len: 200}];
|
string tos = 1 [(validate.rules).string = {max_len: 200}];
|
||||||
string privacy_policy = 3 [(validate.rules).string = {max_len: 200}];
|
string privacy_policy = 3 [(validate.rules).string = {max_len: 200}];
|
||||||
string help = 5 [(validate.rules).string = {max_len: 200}];
|
string help = 5 [(validate.rules).string = {max_len: 200}];
|
||||||
|
string support_email = 7 [(validate.rules).string = {max_len: 200}];
|
||||||
}
|
}
|
||||||
|
|
||||||
message PasswordlessPromptScreenText {
|
message PasswordlessPromptScreenText {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user