mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-05 22:52:46 +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
|
||||
PrivacyLink: https://zitadel.com/docs/legal/privacy-policy
|
||||
HelpLink: ""
|
||||
SupportEmail: ""
|
||||
NotificationPolicy:
|
||||
PasswordChange: true
|
||||
LabelPolicy:
|
||||
|
@ -73,6 +73,7 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
||||
r3.setHelp(map.footerText?.help ?? '');
|
||||
r3.setPrivacyPolicy(map.footerText?.privacyPolicy ?? '');
|
||||
r3.setTos(map.footerText?.tos ?? '');
|
||||
r3.setSupportEmail(map.footerText?.supportEmail ?? '');
|
||||
req.setFooterText(r3);
|
||||
|
||||
const r4 = new InitMFADoneScreenText();
|
||||
|
@ -36,6 +36,12 @@
|
||||
<input cnslInput name="helpLink" formControlName="helpLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'helpLink' }"></template>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
|
@ -7,9 +7,10 @@
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
column-gap: 1rem;
|
||||
width: 75%;
|
||||
|
||||
@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: ['', []],
|
||||
privacyLink: ['', []],
|
||||
helpLink: ['', []],
|
||||
supportEmail: ['', []],
|
||||
});
|
||||
|
||||
this.canWrite$.pipe(take(1)).subscribe((canWrite) => {
|
||||
@ -105,6 +106,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
tosLink: '',
|
||||
privacyLink: '',
|
||||
helpLink: '',
|
||||
supportEmail: '',
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -114,6 +116,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
tosLink: '',
|
||||
privacyLink: '',
|
||||
helpLink: '',
|
||||
supportEmail: '',
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -125,6 +128,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||
(this.service as ManagementService)
|
||||
.addCustomPrivacyPolicy(req)
|
||||
.then(() => {
|
||||
@ -137,6 +141,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||
|
||||
(this.service as ManagementService)
|
||||
.updateCustomPrivacyPolicy(req)
|
||||
@ -151,6 +156,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||
|
||||
(this.service as AdminService)
|
||||
.updatePrivacyPolicy(req)
|
||||
|
@ -53,6 +53,6 @@
|
||||
<cnsl-login-texts [serviceType]="serviceType"></cnsl-login-texts>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentSetting === 'privacypolicy'">
|
||||
<cnsl-privacy-policy [serviceType]="PolicyComponentServiceType.ADMIN"></cnsl-privacy-policy>
|
||||
<cnsl-privacy-policy [serviceType]="serviceType"></cnsl-privacy-policy>
|
||||
</ng-container>
|
||||
</cnsl-sidenav>
|
||||
|
@ -1185,6 +1185,7 @@
|
||||
"TOSLINK": "Link zu den Allgemeinen Geschäftsbedingungen",
|
||||
"POLICYLINK": "Link zur den Datenschutzrichtlinien",
|
||||
"HELPLINK": "Link zur Hilfestellung",
|
||||
"SUPPORTEMAIL": "Support E-Mail",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE": "Standardwerte wiederherstellen",
|
||||
"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",
|
||||
"POLICYLINK": "Link to Privacy Policy",
|
||||
"HELPLINK": "Link to Help",
|
||||
"SUPPORTEMAIL": "Support Email",
|
||||
"SAVED": "Saved successfully!",
|
||||
"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?"
|
||||
|
@ -1185,6 +1185,7 @@
|
||||
"TOSLINK": "Lien vers les conditions d'utilisation",
|
||||
"POLICYLINK": "Lien vers la politique de confidentialité",
|
||||
"HELPLINK": "Lien vers l'aide",
|
||||
"SUPPORTEMAIL": "E-mail d'assistance",
|
||||
"SAVED": "Enregistré avec succès !",
|
||||
"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 ?"
|
||||
|
@ -8,7 +8,7 @@
|
||||
},
|
||||
"FOOTER": {
|
||||
"LINKS": {
|
||||
"CONTACT": "Kontakt",
|
||||
"CONTACT": "Contatto",
|
||||
"TOS": "Terms of Service",
|
||||
"PP": "Privacy Policy"
|
||||
},
|
||||
@ -1186,6 +1186,7 @@
|
||||
"TOSLINK": "Link ai termini di servizio",
|
||||
"POLICYLINK": "Link all'informativa sulla privacy",
|
||||
"HELPLINK": "link per l'aiuto",
|
||||
"SUPPORTEMAIL": "e-mail di supporto",
|
||||
"SAVED": "Salvato con successo!",
|
||||
"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?"
|
||||
|
@ -1185,6 +1185,7 @@
|
||||
"TOSLINK": "Link do warunków korzystania",
|
||||
"POLICYLINK": "Link do polityki prywatności",
|
||||
"HELPLINK": "Link do pomocy",
|
||||
"SUPPORTEMAIL": "E-mail wsparcia",
|
||||
"SAVED": "Pomyślnie zapisano!",
|
||||
"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ć?"
|
||||
|
@ -1184,6 +1184,7 @@
|
||||
"TOSLINK": "链接到服务条款",
|
||||
"POLICYLINK": "链接到隐私政策",
|
||||
"HELPLINK": "链接到帮助",
|
||||
"SUPPORTEMAIL": "支持邮箱",
|
||||
"SAVED": "保存成功!",
|
||||
"RESET_TITLE": "恢复默认值",
|
||||
"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)
|
||||
|
||||
<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
|
||||
|
||||
@ -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
|
||||
- **External Login Check Lifetime** specifies after which period a user has to revalidate the Multi Factor during the login process
|
||||
|
||||
|
||||
## Identity Providers
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
<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
|
||||
|
||||
|
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 |
@ -521,9 +521,10 @@ func (s *Server) getPrivacyPolicy(ctx context.Context, orgID string) (_ *managem
|
||||
}
|
||||
if !queriedPrivacy.IsDefault {
|
||||
return &management_pb.AddCustomPrivacyPolicyRequest{
|
||||
TosLink: queriedPrivacy.TOSLink,
|
||||
PrivacyLink: queriedPrivacy.PrivacyLink,
|
||||
HelpLink: queriedPrivacy.HelpLink,
|
||||
TosLink: queriedPrivacy.TOSLink,
|
||||
PrivacyLink: queriedPrivacy.PrivacyLink,
|
||||
HelpLink: queriedPrivacy.HelpLink,
|
||||
SupportEmail: string(queriedPrivacy.SupportEmail),
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -7,8 +7,9 @@ import (
|
||||
|
||||
func UpdatePrivacyPolicyToDomain(req *admin_pb.UpdatePrivacyPolicyRequest) *domain.PrivacyPolicy {
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||
}
|
||||
}
|
||||
|
@ -7,16 +7,18 @@ import (
|
||||
|
||||
func AddPrivacyPolicyToDomain(req *mgmt_pb.AddCustomPrivacyPolicyRequest) *domain.PrivacyPolicy {
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||
}
|
||||
}
|
||||
|
||||
func UpdatePrivacyPolicyToDomain(req *mgmt_pb.UpdateCustomPrivacyPolicyRequest) *domain.PrivacyPolicy {
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ import (
|
||||
|
||||
func ModelPrivacyPolicyToPb(policy *query.PrivacyPolicy) *policy_pb.PrivacyPolicy {
|
||||
return &policy_pb.PrivacyPolicy{
|
||||
IsDefault: policy.IsDefault,
|
||||
TosLink: policy.TOSLink,
|
||||
PrivacyLink: policy.PrivacyLink,
|
||||
HelpLink: policy.HelpLink,
|
||||
IsDefault: policy.IsDefault,
|
||||
TosLink: policy.TOSLink,
|
||||
PrivacyLink: policy.PrivacyLink,
|
||||
HelpLink: policy.HelpLink,
|
||||
SupportEmail: string(policy.SupportEmail),
|
||||
Details: object.ToViewDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.CreationDate,
|
||||
|
@ -458,6 +458,7 @@ func FooterTextToPb(text domain.FooterText) *text_pb.FooterText {
|
||||
Tos: text.TOS,
|
||||
PrivacyPolicy: text.PrivacyPolicy,
|
||||
Help: text.Help,
|
||||
SupportEmail: text.SupportEmail,
|
||||
}
|
||||
}
|
||||
|
||||
@ -949,5 +950,6 @@ func FooterTextPbToDomain(text *text_pb.FooterText) domain.FooterText {
|
||||
TOS: text.Tos,
|
||||
PrivacyPolicy: text.PrivacyPolicy,
|
||||
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 {
|
||||
baseData.HelpLink = link
|
||||
}
|
||||
if link, err := templates.ParseTemplateText(string(privacyPolicy.SupportEmail), lang); err == nil {
|
||||
baseData.SupportEmail = link
|
||||
}
|
||||
return baseData
|
||||
}
|
||||
|
||||
@ -602,6 +605,7 @@ type baseData struct {
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
SupportEmail string
|
||||
AuthReqID string
|
||||
CSRF template.HTML
|
||||
Nonce string
|
||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
||||
NewPasswordConfirmLabel: Passwort Bestätigung
|
||||
CancelButtonText: abbrechen
|
||||
NextButtonText: weiter
|
||||
Footer: Fusszeile
|
||||
|
||||
PasswordChangeDone:
|
||||
Title: Passwort ändern
|
||||
@ -318,6 +319,7 @@ Footer:
|
||||
Tos: AGB
|
||||
PrivacyPolicy: Datenschutzerklärung
|
||||
Help: Hilfe
|
||||
SupportEmail: Support E-Mail
|
||||
|
||||
Errors:
|
||||
Internal: Es ist ein interner Fehler aufgetreten
|
||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
||||
NewPasswordConfirmLabel: Password confirmation
|
||||
CancelButtonText: cancel
|
||||
NextButtonText: next
|
||||
Footer: Footer
|
||||
|
||||
PasswordChangeDone:
|
||||
Title: Change Password
|
||||
@ -318,6 +319,7 @@ Footer:
|
||||
Tos: TOS
|
||||
PrivacyPolicy: Privacy policy
|
||||
Help: Help
|
||||
SupportEmail: Support E-mail
|
||||
|
||||
Errors:
|
||||
Internal: An internal error occurred
|
||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
||||
NewPasswordConfirmLabel: Confirmation du mot de passe
|
||||
CancelButtonText: annuler
|
||||
NextButtonText: suivant
|
||||
Footer: Bas de page
|
||||
|
||||
PasswordChangeDone:
|
||||
Title: Changer le mot de passe
|
||||
@ -318,6 +319,7 @@ Footer:
|
||||
Tos: TOS
|
||||
PrivacyPolicy: Politique de confidentialité
|
||||
Help: Aide
|
||||
SupportEmail: E-mail d'assistance
|
||||
|
||||
Errors:
|
||||
Internal: Une erreur interne s'est produite
|
||||
@ -408,8 +410,8 @@ Errors:
|
||||
ExternalUserIDEmpty: L'ID de l'utilisateur externe est vide
|
||||
UserDisplayNameEmpty: Le nom d'affichage de l'utilisateur est vide
|
||||
NoExternalUserData: Aucune donnée d'utilisateur externe reçue
|
||||
CreationNotAllowed : La création d'un nouvel utilisateur n'est pas autorisée sur ce fournisseur.
|
||||
LinkingNotAllowed : La création d'un lien vers un utilisateur n'est pas autorisée pour ce fournisseur.
|
||||
CreationNotAllowed: La création d'un nouvel utilisateur n'est pas autorisée sur ce fournisseur.
|
||||
LinkingNotAllowed: La création d'un lien vers un utilisateur n'est pas autorisée pour ce fournisseur.
|
||||
GrantRequired: Connexion impossible. L'utilisateur doit avoir au moins une subvention sur l'application. Veuillez contacter votre administrateur.
|
||||
ProjectRequired: Connexion impossible. L'organisation de l'utilisateur doit être accordée au projet. Veuillez contacter votre administrateur.
|
||||
IdentityProvider:
|
||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
||||
NewPasswordConfirmLabel: Conferma della password
|
||||
CancelButtonText: annulla
|
||||
NextButtonText: Avanti
|
||||
Footer: Piè di pagina
|
||||
|
||||
PasswordChangeDone:
|
||||
Title: Reimposta password
|
||||
@ -318,6 +319,7 @@ Footer:
|
||||
Tos: Termini di servizio
|
||||
PrivacyPolicy: l'informativa sulla privacy
|
||||
Help: Aiuto
|
||||
SupportEmail: E-mail di supporto
|
||||
|
||||
Errors:
|
||||
Internal: Si è verificato un errore interno
|
||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
||||
NewPasswordConfirmLabel: Potwierdzenie hasła
|
||||
CancelButtonText: anuluj
|
||||
NextButtonText: dalej
|
||||
Footer: Stopka
|
||||
|
||||
PasswordChangeDone:
|
||||
Title: Zmiana hasła
|
||||
@ -318,6 +319,7 @@ Footer:
|
||||
Tos: TOS
|
||||
PrivacyPolicy: Polityka prywatności
|
||||
Help: Pomoc
|
||||
SupportEmail: E-mail wsparcia
|
||||
|
||||
Errors:
|
||||
Internal: Wewnętrzny błąd
|
||||
|
@ -172,6 +172,7 @@ PasswordChange:
|
||||
NewPasswordConfirmLabel: 确认密码
|
||||
CancelButtonText: 取消
|
||||
NextButtonText: 继续
|
||||
Footer: 页脚
|
||||
|
||||
PasswordChangeDone:
|
||||
Title: 更改密码
|
||||
@ -318,6 +319,7 @@ Footer:
|
||||
Tos: 服务条款
|
||||
PrivacyPolicy: 隐私政策
|
||||
Help: 帮助
|
||||
SupportEmail: 支持邮箱
|
||||
|
||||
Errors:
|
||||
Internal: 发生了内部错误
|
||||
|
@ -1,20 +1,41 @@
|
||||
{{define "footer"}}
|
||||
<footer>
|
||||
{{ if hasWatermark .LabelPolicy }}
|
||||
<span class="watermark" >
|
||||
<span class="powered">{{t "Footer.PoweredBy"}}</span>
|
||||
<span class="lgn-logo-watermark" sourcelight="logo-light.svg" sourcedark="logo-dark.svg" alt="logo"></span>
|
||||
</span>
|
||||
{{end}}
|
||||
<span class="fill-space"></span>
|
||||
{{ if .TOSLink }}
|
||||
<a href="{{.TOSLink}}" rel="noopener noreferrer" target="_blank" alt="TOS">{{t "Footer.Tos"}}</a>
|
||||
{{ end }}
|
||||
{{ if .PrivacyLink }}
|
||||
<a href="{{.PrivacyLink}}" 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 hasWatermark .LabelPolicy }}
|
||||
<span class="watermark">
|
||||
<span class="powered">{{t "Footer.PoweredBy"}}</span>
|
||||
<span
|
||||
class="lgn-logo-watermark"
|
||||
sourcelight="logo-light.svg"
|
||||
sourcedark="logo-dark.svg"
|
||||
alt="logo"
|
||||
></span>
|
||||
</span>
|
||||
{{end}}
|
||||
<span class="fill-space"></span>
|
||||
{{ if .TOSLink }}
|
||||
<a href="{{.TOSLink}}" rel="noopener noreferrer" target="_blank" alt="TOS"
|
||||
>{{t "Footer.Tos"}}</a
|
||||
>
|
||||
{{ end }} {{ if .PrivacyLink }}
|
||||
<a
|
||||
href="{{.PrivacyLink}}"
|
||||
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}}
|
||||
</footer>
|
||||
{{end}}
|
||||
|
@ -1158,6 +1158,7 @@ func privacyPolicyToDomain(p *query.PrivacyPolicy) *domain.PrivacyPolicy {
|
||||
TOSLink: p.TOSLink,
|
||||
PrivacyLink: p.PrivacyLink,
|
||||
HelpLink: p.HelpLink,
|
||||
SupportEmail: p.SupportEmail,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1093,6 +1093,10 @@ func (c *Commands) createFooterTextEvents(ctx context.Context, agg *eventstore.A
|
||||
if event != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ type CustomLoginTextReadModel struct {
|
||||
FooterTOS string
|
||||
FooterPrivacyPolicy string
|
||||
FooterHelp string
|
||||
FooterHelpLink string
|
||||
FooterSupportEmail string
|
||||
}
|
||||
|
||||
func (wm *CustomLoginTextReadModel) Reduce() error {
|
||||
@ -2515,6 +2515,10 @@ func (wm *CustomLoginTextReadModel) handleFooterTextSetEvent(e *policy.CustomTex
|
||||
wm.FooterHelp = e.Text
|
||||
return
|
||||
}
|
||||
if e.Key == domain.LoginKeyFooterSupportEmail {
|
||||
wm.FooterSupportEmail = e.Text
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.CustomTextRemovedEvent) {
|
||||
@ -2530,4 +2534,8 @@ func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.Custom
|
||||
wm.FooterHelp = ""
|
||||
return
|
||||
}
|
||||
if e.Key == domain.LoginKeyFooterSupportEmail {
|
||||
wm.FooterSupportEmail = ""
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -87,9 +87,10 @@ type InstanceSetup struct {
|
||||
PasswordChange bool
|
||||
}
|
||||
PrivacyPolicy struct {
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
SupportEmail domain.EmailAddress
|
||||
}
|
||||
LabelPolicy struct {
|
||||
PrimaryColor string
|
||||
@ -242,7 +243,7 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
||||
prepareAddSecondFactorToDefaultLoginPolicy(instanceAgg, domain.SecondFactorTypeU2F),
|
||||
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),
|
||||
prepareAddDefaultLockoutPolicy(instanceAgg, setup.LockoutPolicy.MaxAttempts, setup.LockoutPolicy.ShouldShowLockoutFailure),
|
||||
|
||||
|
@ -127,6 +127,7 @@ func writeModelToPrivacyPolicy(wm *PrivacyPolicyWriteModel) *domain.PrivacyPolic
|
||||
TOSLink: wm.TOSLink,
|
||||
PrivacyLink: wm.PrivacyLink,
|
||||
HelpLink: wm.HelpLink,
|
||||
SupportEmail: wm.SupportEmail,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,6 @@ func (c *Commands) setCustomInstanceLoginText(ctx context.Context, instanceAgg *
|
||||
if !text.IsValid() {
|
||||
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "Instance-kd9fs", "Errors.CustomText.Invalid")
|
||||
}
|
||||
|
||||
existingLoginText, err := c.defaultLoginTextWriteModelByID(ctx, text.Language)
|
||||
if err != nil {
|
||||
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,
|
||||
),
|
||||
),
|
||||
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",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
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,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithInstanceID(
|
||||
"INSTANCE",
|
||||
instance.NewCustomTextSetEvent(context.Background(),
|
||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -4310,6 +4323,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&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,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithInstanceID(
|
||||
"INSTANCE",
|
||||
instance.NewCustomTextSetEvent(context.Background(),
|
||||
&instance.NewAggregate("INSTANCE").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusherWithInstanceID(
|
||||
"INSTANCE",
|
||||
instance.NewCustomTextRemovedEvent(context.Background(),
|
||||
@ -6996,6 +7021,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&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(
|
||||
[]*repository.Event{
|
||||
@ -8313,6 +8344,12 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&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",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
Help: "Help",
|
||||
SupportEmail: "Support Email",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -12,9 +12,9 @@ import (
|
||||
"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())
|
||||
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 {
|
||||
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) {
|
||||
if policy.SupportEmail != "" {
|
||||
if err := policy.SupportEmail.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy.SupportEmail = policy.SupportEmail.Normalize()
|
||||
}
|
||||
|
||||
existingPolicy, err := c.defaultPrivacyPolicyWriteModelByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -35,7 +42,7 @@ func (c *Commands) ChangeDefaultPrivacyPolicy(ctx context.Context, policy *domai
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "INSTANCE-9jJfs", "Errors.IAM.PrivacyPolicy.NotChanged")
|
||||
}
|
||||
@ -81,8 +88,15 @@ func prepareAddDefaultPrivacyPolicy(
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
supportEmail domain.EmailAddress,
|
||||
) preparation.Validation {
|
||||
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) {
|
||||
writeModel := NewInstancePrivacyPolicyWriteModel(ctx)
|
||||
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 []eventstore.Command{
|
||||
instance.NewPrivacyPolicyAddedEvent(ctx, &a.Aggregate, tosLink, privacyLink, helpLink),
|
||||
instance.NewPrivacyPolicyAddedEvent(ctx, &a.Aggregate, tosLink, privacyLink, helpLink, supportEmail),
|
||||
}, nil
|
||||
}, nil
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||
@ -57,6 +58,7 @@ func (wm *InstancePrivacyPolicyWriteModel) NewChangedEvent(
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
supportEmail domain.EmailAddress,
|
||||
) (*instance.PrivacyPolicyChangedEvent, bool) {
|
||||
|
||||
changes := make([]policy.PrivacyPolicyChanges, 0)
|
||||
@ -69,6 +71,9 @@ func (wm *InstancePrivacyPolicyWriteModel) NewChangedEvent(
|
||||
if wm.HelpLink != helpLink {
|
||||
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
||||
}
|
||||
if wm.SupportEmail != supportEmail {
|
||||
changes = append(changes, policy.ChangeSupportEmail(supportEmail))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
@ -22,10 +22,11 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
tosLink string
|
||||
privacyLink string
|
||||
helpLink string
|
||||
ctx context.Context
|
||||
tosLink string
|
||||
privacyLink string
|
||||
helpLink string
|
||||
supportEmail domain.EmailAddress
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
@ -49,16 +50,18 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
tosLink: "TOSLink",
|
||||
privacyLink: "PrivacyLink",
|
||||
helpLink: "HelpLink",
|
||||
ctx: context.Background(),
|
||||
tosLink: "TOSLink",
|
||||
privacyLink: "PrivacyLink",
|
||||
helpLink: "HelpLink",
|
||||
supportEmail: "support@example.com",
|
||||
},
|
||||
res: res{
|
||||
err: caos_errs.IsErrorAlreadyExists,
|
||||
@ -79,6 +82,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -86,10 +90,11 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||
tosLink: "TOSLink",
|
||||
privacyLink: "PrivacyLink",
|
||||
helpLink: "HelpLink",
|
||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||
tosLink: "TOSLink",
|
||||
privacyLink: "PrivacyLink",
|
||||
helpLink: "HelpLink",
|
||||
supportEmail: "support@example.com",
|
||||
},
|
||||
res: res{
|
||||
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",
|
||||
fields: fields{
|
||||
@ -112,6 +135,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -119,10 +143,11 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||
tosLink: "",
|
||||
privacyLink: "",
|
||||
helpLink: "",
|
||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||
tosLink: "",
|
||||
privacyLink: "",
|
||||
helpLink: "",
|
||||
supportEmail: "",
|
||||
},
|
||||
res: res{
|
||||
want: &domain.ObjectDetails{
|
||||
@ -136,7 +161,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
r := &Commands{
|
||||
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 {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@ -179,9 +204,10 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -200,6 +226,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -208,15 +235,36 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
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",
|
||||
fields: fields{
|
||||
@ -229,6 +277,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -239,6 +288,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
"TOSLinkChanged",
|
||||
"PrivacyLinkChanged",
|
||||
"HelpLinkChanged",
|
||||
"support2@example.com",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -248,9 +298,10 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLinkChanged",
|
||||
PrivacyLink: "PrivacyLinkChanged",
|
||||
HelpLink: "HelpLinkChanged",
|
||||
TOSLink: "TOSLinkChanged",
|
||||
PrivacyLink: "PrivacyLinkChanged",
|
||||
HelpLink: "HelpLinkChanged",
|
||||
SupportEmail: "support2@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -259,9 +310,10 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
AggregateID: "INSTANCE",
|
||||
ResourceOwner: "INSTANCE",
|
||||
},
|
||||
TOSLink: "TOSLinkChanged",
|
||||
PrivacyLink: "PrivacyLinkChanged",
|
||||
HelpLink: "HelpLinkChanged",
|
||||
TOSLink: "TOSLinkChanged",
|
||||
PrivacyLink: "PrivacyLinkChanged",
|
||||
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,
|
||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||
[]policy.PrivacyPolicyChanges{
|
||||
policy.ChangeTOSLink(tosLink),
|
||||
policy.ChangePrivacyLink(privacyLink),
|
||||
policy.ChangeHelpLink(helpLink),
|
||||
policy.ChangeSupportEmail(domain.EmailAddress(supportEmail)),
|
||||
},
|
||||
)
|
||||
return event
|
||||
|
@ -50,5 +50,6 @@ func orgWriteModelToPrivacyPolicy(wm *OrgPrivacyPolicyWriteModel) *domain.Privac
|
||||
TOSLink: wm.TOSLink,
|
||||
PrivacyLink: wm.PrivacyLink,
|
||||
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,
|
||||
),
|
||||
),
|
||||
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",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
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,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextSetEvent(context.Background(),
|
||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -3653,6 +3664,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&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,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextSetEvent(context.Background(),
|
||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, "Support Email", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextRemovedEvent(context.Background(),
|
||||
&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,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextRemovedEvent(context.Background(),
|
||||
&org.NewAggregate("org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterSupportEmail, language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -6983,6 +7009,11 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&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",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
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) {
|
||||
|
||||
if policy.SupportEmail != "" {
|
||||
if err := policy.SupportEmail.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy.SupportEmail = policy.SupportEmail.Normalize()
|
||||
}
|
||||
|
||||
if resourceOwner == "" {
|
||||
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,
|
||||
policy.TOSLink,
|
||||
policy.PrivacyLink,
|
||||
policy.HelpLink))
|
||||
policy.HelpLink,
|
||||
policy.SupportEmail))
|
||||
if err != nil {
|
||||
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) {
|
||||
|
||||
if policy.SupportEmail != "" {
|
||||
if err := policy.SupportEmail.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy.SupportEmail = policy.SupportEmail.Normalize()
|
||||
}
|
||||
|
||||
if resourceOwner == "" {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-22N89f", "Errors.ResourceOwnerMissing")
|
||||
}
|
||||
|
||||
existingPolicy := NewOrgPrivacyPolicyWriteModel(resourceOwner)
|
||||
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
||||
existingPolicy, err := c.orgPrivacyPolicyWriteModelByID(ctx, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -75,7 +91,7 @@ func (c *Commands) ChangePrivacyPolicy(ctx context.Context, resourceOwner string
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4N9fs", "Errors.Org.PrivacyPolicy.NotChanged")
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package command
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/repository/org"
|
||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||
)
|
||||
@ -59,6 +59,7 @@ func (wm *OrgPrivacyPolicyWriteModel) NewChangedEvent(
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
supportEmail domain.EmailAddress,
|
||||
) (*org.PrivacyPolicyChangedEvent, bool) {
|
||||
|
||||
changes := make([]policy.PrivacyPolicyChanges, 0)
|
||||
@ -71,6 +72,9 @@ func (wm *OrgPrivacyPolicyWriteModel) NewChangedEvent(
|
||||
if wm.HelpLink != helpLink {
|
||||
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
||||
}
|
||||
if wm.SupportEmail != supportEmail {
|
||||
changes = append(changes, policy.ChangeSupportEmail(supportEmail))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
@ -44,9 +44,10 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -65,6 +66,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -74,9 +76,10 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -97,6 +100,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -107,9 +111,10 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -118,14 +123,36 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
AggregateID: "org1",
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
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{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
@ -138,6 +165,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -148,9 +176,10 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
SupportEmail: "",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -159,9 +188,10 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
AggregateID: "org1",
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
SupportEmail: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -214,9 +244,10 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -235,9 +266,10 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -256,6 +288,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -265,15 +298,32 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
SupportEmail: "support@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
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",
|
||||
fields: fields{
|
||||
@ -286,13 +336,14 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "TOSLinkChange", "PrivacyLinkChange", "HelpLinkChange"),
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "TOSLinkChange", "PrivacyLinkChange", "HelpLinkChange", "support2@example.com"),
|
||||
),
|
||||
},
|
||||
),
|
||||
@ -302,9 +353,10 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLinkChange",
|
||||
PrivacyLink: "PrivacyLinkChange",
|
||||
HelpLink: "HelpLinkChange",
|
||||
TOSLink: "TOSLinkChange",
|
||||
PrivacyLink: "PrivacyLinkChange",
|
||||
HelpLink: "HelpLinkChange",
|
||||
SupportEmail: "support2@example.com",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -313,9 +365,10 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
AggregateID: "org1",
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
TOSLink: "TOSLinkChange",
|
||||
PrivacyLink: "PrivacyLinkChange",
|
||||
HelpLink: "HelpLinkChange",
|
||||
TOSLink: "TOSLinkChange",
|
||||
PrivacyLink: "PrivacyLinkChange",
|
||||
HelpLink: "HelpLinkChange",
|
||||
SupportEmail: "support2@example.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -331,13 +384,14 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
"support@example.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "", "", ""),
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "", "", "", ""),
|
||||
),
|
||||
},
|
||||
),
|
||||
@ -347,9 +401,10 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
SupportEmail: "",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -358,9 +413,10 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
AggregateID: "org1",
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
SupportEmail: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -444,6 +500,7 @@ func TestCommandSide_RemovePrivacyPolicy(t *testing.T) {
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"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,
|
||||
&org.NewAggregate(orgID).Aggregate,
|
||||
[]policy.PrivacyPolicyChanges{
|
||||
policy.ChangeTOSLink(tosLink),
|
||||
policy.ChangePrivacyLink(privacyLink),
|
||||
policy.ChangeHelpLink(helpLink),
|
||||
policy.ChangeSupportEmail(domain.EmailAddress(supportEmail)),
|
||||
},
|
||||
)
|
||||
return event
|
||||
|
@ -9,10 +9,11 @@ import (
|
||||
type PrivacyPolicyWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
State domain.PolicyState
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
SupportEmail domain.EmailAddress
|
||||
State domain.PolicyState
|
||||
}
|
||||
|
||||
func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
||||
@ -22,6 +23,7 @@ func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
||||
wm.TOSLink = e.TOSLink
|
||||
wm.PrivacyLink = e.PrivacyLink
|
||||
wm.HelpLink = e.HelpLink
|
||||
wm.SupportEmail = e.SupportEmail
|
||||
wm.State = domain.PolicyStateActive
|
||||
case *policy.PrivacyPolicyChangedEvent:
|
||||
if e.PrivacyLink != nil {
|
||||
@ -33,6 +35,9 @@ func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
||||
if e.HelpLink != nil {
|
||||
wm.HelpLink = *e.HelpLink
|
||||
}
|
||||
if e.SupportEmail != nil {
|
||||
wm.SupportEmail = *e.SupportEmail
|
||||
}
|
||||
case *policy.PrivacyPolicyRemovedEvent:
|
||||
wm.State = domain.PolicyStateRemoved
|
||||
}
|
||||
|
@ -296,6 +296,7 @@ const (
|
||||
LoginKeyFooterTOS = LoginKeyFooter + "Tos"
|
||||
LoginKeyFooterPrivacyPolicy = LoginKeyFooter + "PrivacyPolicy"
|
||||
LoginKeyFooterHelp = LoginKeyFooter + "Help"
|
||||
LoginKeyFooterSupportEmail = LoginKeyFooter + "SupportEmail"
|
||||
)
|
||||
|
||||
type CustomLoginText struct {
|
||||
@ -639,6 +640,7 @@ type FooterText struct {
|
||||
TOS string
|
||||
PrivacyPolicy string
|
||||
Help string
|
||||
SupportEmail string
|
||||
}
|
||||
|
||||
type PasswordlessPromptScreenText struct {
|
||||
|
@ -10,7 +10,8 @@ type PrivacyPolicy struct {
|
||||
State PolicyState
|
||||
Default bool
|
||||
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
SupportEmail EmailAddress
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ type PrivacyPolicyView struct {
|
||||
AggregateID string
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
SupportEmail string
|
||||
Default bool
|
||||
|
||||
CreationDate time.Time
|
||||
|
@ -1181,4 +1181,7 @@ func footerKeyToDomain(text *CustomText, result *domain.CustomLoginText) {
|
||||
if text.Key == domain.LoginKeyFooterHelp {
|
||||
result.Footer.Help = text.Text
|
||||
}
|
||||
if text.Key == domain.LoginKeyFooterSupportEmail {
|
||||
result.Footer.SupportEmail = text.Text
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,10 @@ type PrivacyPolicy struct {
|
||||
ResourceOwner string
|
||||
State domain.PolicyState
|
||||
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
SupportEmail domain.EmailAddress
|
||||
|
||||
IsDefault bool
|
||||
}
|
||||
@ -72,6 +73,10 @@ var (
|
||||
name: projection.PrivacyPolicyHelpLinkCol,
|
||||
table: privacyTable,
|
||||
}
|
||||
PrivacyColSupportEmail = Column{
|
||||
name: projection.PrivacyPolicySupportEmailCol,
|
||||
table: privacyTable,
|
||||
}
|
||||
PrivacyColIsDefault = Column{
|
||||
name: projection.PrivacyPolicyIsDefaultCol,
|
||||
table: privacyTable,
|
||||
@ -148,6 +153,7 @@ func preparePrivacyPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
|
||||
PrivacyColPrivacyLink.identifier(),
|
||||
PrivacyColTOSLink.identifier(),
|
||||
PrivacyColHelpLink.identifier(),
|
||||
PrivacyColSupportEmail.identifier(),
|
||||
PrivacyColIsDefault.identifier(),
|
||||
PrivacyColState.identifier(),
|
||||
).
|
||||
@ -164,6 +170,7 @@ func preparePrivacyPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
|
||||
&policy.PrivacyLink,
|
||||
&policy.TOSLink,
|
||||
&policy.HelpLink,
|
||||
&policy.SupportEmail,
|
||||
&policy.IsDefault,
|
||||
&policy.State,
|
||||
)
|
||||
@ -179,9 +186,10 @@ func preparePrivacyPolicyQuery(ctx context.Context, db prepareDatabase) (sq.Sele
|
||||
|
||||
func (p *PrivacyPolicy) ToDomain() *domain.PrivacyPolicy {
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: p.TOSLink,
|
||||
PrivacyLink: p.PrivacyLink,
|
||||
HelpLink: p.HelpLink,
|
||||
Default: p.IsDefault,
|
||||
TOSLink: p.TOSLink,
|
||||
PrivacyLink: p.PrivacyLink,
|
||||
HelpLink: p.HelpLink,
|
||||
SupportEmail: p.SupportEmail,
|
||||
Default: p.IsDefault,
|
||||
}
|
||||
}
|
||||
|
@ -13,17 +13,18 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
preparePrivacyPolicyStmt = `SELECT projections.privacy_policies2.id,` +
|
||||
` projections.privacy_policies2.sequence,` +
|
||||
` projections.privacy_policies2.creation_date,` +
|
||||
` projections.privacy_policies2.change_date,` +
|
||||
` projections.privacy_policies2.resource_owner,` +
|
||||
` projections.privacy_policies2.privacy_link,` +
|
||||
` projections.privacy_policies2.tos_link,` +
|
||||
` projections.privacy_policies2.help_link,` +
|
||||
` projections.privacy_policies2.is_default,` +
|
||||
` projections.privacy_policies2.state` +
|
||||
` FROM projections.privacy_policies2` +
|
||||
preparePrivacyPolicyStmt = `SELECT projections.privacy_policies3.id,` +
|
||||
` projections.privacy_policies3.sequence,` +
|
||||
` projections.privacy_policies3.creation_date,` +
|
||||
` projections.privacy_policies3.change_date,` +
|
||||
` projections.privacy_policies3.resource_owner,` +
|
||||
` projections.privacy_policies3.privacy_link,` +
|
||||
` projections.privacy_policies3.tos_link,` +
|
||||
` projections.privacy_policies3.help_link,` +
|
||||
` projections.privacy_policies3.support_email,` +
|
||||
` projections.privacy_policies3.is_default,` +
|
||||
` projections.privacy_policies3.state` +
|
||||
` FROM projections.privacy_policies3` +
|
||||
` AS OF SYSTEM TIME '-1 ms'`
|
||||
preparePrivacyPolicyCols = []string{
|
||||
"id",
|
||||
@ -34,6 +35,7 @@ var (
|
||||
"privacy_link",
|
||||
"tos_link",
|
||||
"help_link",
|
||||
"support_email",
|
||||
"is_default",
|
||||
"state",
|
||||
}
|
||||
@ -84,6 +86,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
"privacy.ch",
|
||||
"tos.ch",
|
||||
"help.ch",
|
||||
"support@example.com",
|
||||
true,
|
||||
domain.PolicyStateActive,
|
||||
},
|
||||
@ -99,6 +102,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
PrivacyLink: "privacy.ch",
|
||||
TOSLink: "tos.ch",
|
||||
HelpLink: "help.ch",
|
||||
SupportEmail: "support@example.com",
|
||||
IsDefault: true,
|
||||
},
|
||||
},
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
PrivacyPolicyTable = "projections.privacy_policies2"
|
||||
PrivacyPolicyTable = "projections.privacy_policies3"
|
||||
|
||||
PrivacyPolicyIDCol = "id"
|
||||
PrivacyPolicyCreationDateCol = "creation_date"
|
||||
@ -27,6 +27,7 @@ const (
|
||||
PrivacyPolicyPrivacyLinkCol = "privacy_link"
|
||||
PrivacyPolicyTOSLinkCol = "tos_link"
|
||||
PrivacyPolicyHelpLinkCol = "help_link"
|
||||
PrivacyPolicySupportEmailCol = "support_email"
|
||||
PrivacyPolicyOwnerRemovedCol = "owner_removed"
|
||||
)
|
||||
|
||||
@ -51,6 +52,7 @@ func newPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandle
|
||||
crdb.NewColumn(PrivacyPolicyPrivacyLinkCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicyTOSLinkCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicyHelpLinkCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicySupportEmailCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
|
||||
},
|
||||
crdb.NewPrimaryKey(PrivacyPolicyInstanceIDCol, PrivacyPolicyIDCol),
|
||||
@ -128,6 +130,7 @@ func (p *privacyPolicyProjection) reduceAdded(event eventstore.Event) (*handler.
|
||||
handler.NewCol(PrivacyPolicyPrivacyLinkCol, policyEvent.PrivacyLink),
|
||||
handler.NewCol(PrivacyPolicyTOSLinkCol, policyEvent.TOSLink),
|
||||
handler.NewCol(PrivacyPolicyHelpLinkCol, policyEvent.HelpLink),
|
||||
handler.NewCol(PrivacyPolicySupportEmailCol, policyEvent.SupportEmail),
|
||||
handler.NewCol(PrivacyPolicyIsDefaultCol, isDefault),
|
||||
handler.NewCol(PrivacyPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner),
|
||||
handler.NewCol(PrivacyPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
|
||||
@ -157,6 +160,9 @@ func (p *privacyPolicyProjection) reduceChanged(event eventstore.Event) (*handle
|
||||
if policyEvent.HelpLink != nil {
|
||||
cols = append(cols, handler.NewCol(PrivacyPolicyHelpLinkCol, *policyEvent.HelpLink))
|
||||
}
|
||||
if policyEvent.SupportEmail != nil {
|
||||
cols = append(cols, handler.NewCol(PrivacyPolicySupportEmailCol, *policyEvent.SupportEmail))
|
||||
}
|
||||
return crdb.NewUpdateStatement(
|
||||
&policyEvent,
|
||||
cols,
|
||||
|
@ -31,8 +31,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
"helpLink": "http://help.link",
|
||||
"supportEmail": "support@example.com"}`),
|
||||
), org.PrivacyPolicyAddedEventMapper),
|
||||
},
|
||||
reduce: (&privacyPolicyProjection{}).reduceAdded,
|
||||
@ -43,7 +43,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@ -53,6 +53,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
domain.EmailAddress("support@example.com"),
|
||||
false,
|
||||
"ro-id",
|
||||
"instance-id",
|
||||
@ -72,8 +73,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
"helpLink": "http://help.link",
|
||||
"supportEmail": "support@example.com"}`),
|
||||
), org.PrivacyPolicyChangedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
@ -83,13 +84,14 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
domain.EmailAddress("support@example.com"),
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
@ -115,7 +117,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@ -141,7 +143,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.privacy_policies2 WHERE (instance_id = $1)",
|
||||
expectedStmt: "DELETE FROM projections.privacy_policies3 WHERE (instance_id = $1)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
},
|
||||
@ -160,8 +162,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
"helpLink": "http://help.link",
|
||||
"supportEmail": "support@example.com"}`),
|
||||
), instance.PrivacyPolicyAddedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
@ -171,7 +173,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@ -181,6 +183,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
domain.EmailAddress("support@example.com"),
|
||||
true,
|
||||
"ro-id",
|
||||
"instance-id",
|
||||
@ -200,8 +203,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
"helpLink": "http://help.link",
|
||||
"supportEmail": "support@example.com"}`),
|
||||
), instance.PrivacyPolicyChangedEventMapper),
|
||||
},
|
||||
want: wantReduce{
|
||||
@ -211,13 +214,14 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
domain.EmailAddress("support@example.com"),
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
@ -243,7 +247,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
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{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
|
@ -3,8 +3,8 @@ package instance
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||
)
|
||||
@ -24,6 +24,7 @@ func NewPrivacyPolicyAddedEvent(
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
supportEmail domain.EmailAddress,
|
||||
) *PrivacyPolicyAddedEvent {
|
||||
return &PrivacyPolicyAddedEvent{
|
||||
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
||||
@ -33,7 +34,8 @@ func NewPrivacyPolicyAddedEvent(
|
||||
PrivacyPolicyAddedEventType),
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink),
|
||||
helpLink,
|
||||
supportEmail),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@ package org
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||
"github.com/zitadel/zitadel/internal/repository/policy"
|
||||
)
|
||||
@ -25,6 +25,7 @@ func NewPrivacyPolicyAddedEvent(
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
supportEmail domain.EmailAddress,
|
||||
) *PrivacyPolicyAddedEvent {
|
||||
return &PrivacyPolicyAddedEvent{
|
||||
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
||||
@ -34,7 +35,8 @@ func NewPrivacyPolicyAddedEvent(
|
||||
PrivacyPolicyAddedEventType),
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink),
|
||||
helpLink,
|
||||
supportEmail),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,9 @@ package policy
|
||||
import (
|
||||
"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/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||
)
|
||||
|
||||
@ -18,9 +18,10 @@ const (
|
||||
type PrivacyPolicyAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
TOSLink string `json:"tosLink,omitempty"`
|
||||
PrivacyLink string `json:"privacyLink,omitempty"`
|
||||
HelpLink string `json:"helpLink,omitempty"`
|
||||
TOSLink string `json:"tosLink,omitempty"`
|
||||
PrivacyLink string `json:"privacyLink,omitempty"`
|
||||
HelpLink string `json:"helpLink,omitempty"`
|
||||
SupportEmail domain.EmailAddress `json:"supportEmail,omitempty"`
|
||||
}
|
||||
|
||||
func (e *PrivacyPolicyAddedEvent) Data() interface{} {
|
||||
@ -36,12 +37,14 @@ func NewPrivacyPolicyAddedEvent(
|
||||
tosLink,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
supportEmail domain.EmailAddress,
|
||||
) *PrivacyPolicyAddedEvent {
|
||||
return &PrivacyPolicyAddedEvent{
|
||||
BaseEvent: *base,
|
||||
TOSLink: tosLink,
|
||||
PrivacyLink: privacyLink,
|
||||
HelpLink: helpLink,
|
||||
BaseEvent: *base,
|
||||
TOSLink: tosLink,
|
||||
PrivacyLink: privacyLink,
|
||||
HelpLink: helpLink,
|
||||
SupportEmail: supportEmail,
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,9 +63,10 @@ func PrivacyPolicyAddedEventMapper(event *repository.Event) (eventstore.Event, e
|
||||
type PrivacyPolicyChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
TOSLink *string `json:"tosLink,omitempty"`
|
||||
PrivacyLink *string `json:"privacyLink,omitempty"`
|
||||
HelpLink *string `json:"helpLink,omitempty"`
|
||||
TOSLink *string `json:"tosLink,omitempty"`
|
||||
PrivacyLink *string `json:"privacyLink,omitempty"`
|
||||
HelpLink *string `json:"helpLink,omitempty"`
|
||||
SupportEmail *domain.EmailAddress `json:"supportEmail,omitempty"`
|
||||
}
|
||||
|
||||
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) {
|
||||
e := &PrivacyPolicyChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
|
@ -5460,6 +5460,13 @@ message UpdatePrivacyPolicyRequest {
|
||||
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 {
|
||||
|
@ -9834,6 +9834,13 @@ message AddCustomPrivacyPolicyRequest {
|
||||
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 {
|
||||
@ -9859,6 +9866,13 @@ message UpdateCustomPrivacyPolicyRequest {
|
||||
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 {
|
||||
|
@ -4,6 +4,7 @@ import "zitadel/object.proto";
|
||||
import "zitadel/idp.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
package zitadel.policy.v1;
|
||||
|
||||
@ -345,6 +346,13 @@ message PrivacyPolicy {
|
||||
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 {
|
||||
|
@ -394,11 +394,12 @@ message LogoutDoneScreenText {
|
||||
}
|
||||
|
||||
message FooterText {
|
||||
reserved 2, 4, 6;
|
||||
reserved 2, 4, 6, 8;
|
||||
reserved "tos_link", "privacy_policy_link", "help_link";
|
||||
string tos = 1 [(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 support_email = 7 [(validate.rules).string = {max_len: 200}];
|
||||
}
|
||||
|
||||
message PasswordlessPromptScreenText {
|
||||
|
Loading…
x
Reference in New Issue
Block a user