- Add site-wide option DEFAULT_KEEP_EMAIL_PRIVATE. - Add the new option to the install and admin/config pages. - Add the new option to app.ini in the service section. - Add the new option to the settings struct. - Add English text strings to i18n. - Add field KeepEmailPrivate to user struct. - Add field KeepEmailPrivate to user form. - Add option to UI. - Add using noreply email address if user has "Keep Email Private". An email address <LowerName>@<NO_REPLY_ADDRESS> is now used in commit messages (and hopefully all other git log relevant places). The change relies on the fact that git commands should use user.NetGitSig(). - Add hiding of email address in UI, if user has set "Keep Email Private". - Add condition to show email address only on explore/users and user pages, if user has not set "Keep Email Private". - Add noreply email in API if set "Keep Email Private". - Add a new service setting NO_REPLY_ADDRESS. The value of this setting is used as the domain part for the user's email address in git log, iff he decides to keep his email address private. If the user decides to keep his email address private and this option is not set 'noreply.example.org' is used, which no MTA should send email to. Add NO_REPLY_ADDRESS to conf/app.ini.
This commit is contained in:
		
							parent
							
								
									6072b03291
								
							
						
					
					
						commit
						51d578ff33
					
				
					 12 changed files with 88 additions and 28 deletions
				
			
		
							
								
								
									
										7
									
								
								conf/app.ini
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								conf/app.ini
									
									
									
									
										vendored
									
									
								
							|  | @ -190,6 +190,13 @@ ENABLE_REVERSE_PROXY_AUTHENTICATION = false | ||||||
| ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false | ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false | ||||||
| ; Enable captcha validation for registration | ; Enable captcha validation for registration | ||||||
| ENABLE_CAPTCHA = true | ENABLE_CAPTCHA = true | ||||||
|  | ; Default value for KeepEmailPrivate | ||||||
|  | ; New user will get the value of this setting copied into their profile | ||||||
|  | DEFAULT_KEEP_EMAIL_PRIVATE = false | ||||||
|  | ; Default value for the domain part of the user's email address in the git log | ||||||
|  | ; if he has set KeepEmailPrivate true. The user's email replaced with a | ||||||
|  | ; concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. | ||||||
|  | NO_REPLY_ADDRESS = noreply.example.org | ||||||
| 
 | 
 | ||||||
| [webhook] | [webhook] | ||||||
| ; Hook task queue length, increase if webhook shooting starts hanging | ; Hook task queue length, increase if webhook shooting starts hanging | ||||||
|  |  | ||||||
|  | @ -75,19 +75,20 @@ type User struct { | ||||||
| 	Name      string `xorm:"UNIQUE NOT NULL"` | 	Name      string `xorm:"UNIQUE NOT NULL"` | ||||||
| 	FullName  string | 	FullName  string | ||||||
| 	// Email is the primary email address (to be used for communication)
 | 	// Email is the primary email address (to be used for communication)
 | ||||||
| 	Email       string `xorm:"NOT NULL"` | 	Email            string `xorm:"NOT NULL"` | ||||||
| 	Passwd      string `xorm:"NOT NULL"` | 	KeepEmailPrivate bool | ||||||
| 	LoginType   LoginType | 	Passwd           string `xorm:"NOT NULL"` | ||||||
| 	LoginSource int64 `xorm:"NOT NULL DEFAULT 0"` | 	LoginType        LoginType | ||||||
| 	LoginName   string | 	LoginSource      int64 `xorm:"NOT NULL DEFAULT 0"` | ||||||
| 	Type        UserType | 	LoginName        string | ||||||
| 	OwnedOrgs   []*User       `xorm:"-"` | 	Type             UserType | ||||||
| 	Orgs        []*User       `xorm:"-"` | 	OwnedOrgs        []*User       `xorm:"-"` | ||||||
| 	Repos       []*Repository `xorm:"-"` | 	Orgs             []*User       `xorm:"-"` | ||||||
| 	Location    string | 	Repos            []*Repository `xorm:"-"` | ||||||
| 	Website     string | 	Location         string | ||||||
| 	Rands       string `xorm:"VARCHAR(10)"` | 	Website          string | ||||||
| 	Salt        string `xorm:"VARCHAR(10)"` | 	Rands            string `xorm:"VARCHAR(10)"` | ||||||
|  | 	Salt             string `xorm:"VARCHAR(10)"` | ||||||
| 
 | 
 | ||||||
| 	Created       time.Time `xorm:"-"` | 	Created       time.Time `xorm:"-"` | ||||||
| 	CreatedUnix   int64     `xorm:"INDEX"` | 	CreatedUnix   int64     `xorm:"INDEX"` | ||||||
|  | @ -170,13 +171,22 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // getEmail returns an noreply email, if the user has set to keep his
 | ||||||
|  | // email address private, otherwise the primary email address.
 | ||||||
|  | func (u *User) getEmail() string { | ||||||
|  | 	if u.KeepEmailPrivate { | ||||||
|  | 		return fmt.Sprintf("%s@%s", u.LowerName, setting.Service.NoReplyAddress) | ||||||
|  | 	} | ||||||
|  | 	return u.Email | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // APIFormat converts a User to api.User
 | // APIFormat converts a User to api.User
 | ||||||
| func (u *User) APIFormat() *api.User { | func (u *User) APIFormat() *api.User { | ||||||
| 	return &api.User{ | 	return &api.User{ | ||||||
| 		ID:        u.ID, | 		ID:        u.ID, | ||||||
| 		UserName:  u.Name, | 		UserName:  u.Name, | ||||||
| 		FullName:  u.FullName, | 		FullName:  u.FullName, | ||||||
| 		Email:     u.Email, | 		Email:     u.getEmail(), | ||||||
| 		AvatarURL: u.AvatarLink(), | 		AvatarURL: u.AvatarLink(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -361,7 +371,7 @@ func (u *User) GetFollowing(page int) ([]*User, error) { | ||||||
| func (u *User) NewGitSig() *git.Signature { | func (u *User) NewGitSig() *git.Signature { | ||||||
| 	return &git.Signature{ | 	return &git.Signature{ | ||||||
| 		Name:  u.DisplayName(), | 		Name:  u.DisplayName(), | ||||||
| 		Email: u.Email, | 		Email: u.getEmail(), | ||||||
| 		When:  time.Now(), | 		When:  time.Now(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -616,6 +626,8 @@ func CreateUser(u *User) (err error) { | ||||||
| 		return ErrEmailAlreadyUsed{u.Email} | 		return ErrEmailAlreadyUsed{u.Email} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate | ||||||
|  | 
 | ||||||
| 	u.LowerName = strings.ToLower(u.Name) | 	u.LowerName = strings.ToLower(u.Name) | ||||||
| 	u.AvatarEmail = u.Email | 	u.AvatarEmail = u.Email | ||||||
| 	u.Avatar = base.HashEmail(u.AvatarEmail) | 	u.Avatar = base.HashEmail(u.AvatarEmail) | ||||||
|  |  | ||||||
|  | @ -38,12 +38,14 @@ type InstallForm struct { | ||||||
| 	RegisterConfirm bool | 	RegisterConfirm bool | ||||||
| 	MailNotify      bool | 	MailNotify      bool | ||||||
| 
 | 
 | ||||||
| 	OfflineMode           bool | 	OfflineMode             bool | ||||||
| 	DisableGravatar       bool | 	DisableGravatar         bool | ||||||
| 	EnableFederatedAvatar bool | 	EnableFederatedAvatar   bool | ||||||
| 	DisableRegistration   bool | 	DisableRegistration     bool | ||||||
| 	EnableCaptcha         bool | 	EnableCaptcha           bool | ||||||
| 	RequireSignInView     bool | 	RequireSignInView       bool | ||||||
|  | 	DefaultKeepEmailPrivate bool | ||||||
|  | 	NoReplyAddress          string | ||||||
| 
 | 
 | ||||||
| 	AdminName          string `binding:"OmitEmpty;AlphaDashDot;MaxSize(30)" locale:"install.admin_name"` | 	AdminName          string `binding:"OmitEmpty;AlphaDashDot;MaxSize(30)" locale:"install.admin_name"` | ||||||
| 	AdminPasswd        string `binding:"OmitEmpty;MaxSize(255)" locale:"install.admin_password"` | 	AdminPasswd        string `binding:"OmitEmpty;MaxSize(255)" locale:"install.admin_password"` | ||||||
|  | @ -97,11 +99,12 @@ func (f *SignInForm) Validate(ctx *macaron.Context, errs binding.Errors) binding | ||||||
| 
 | 
 | ||||||
| // UpdateProfileForm form for updating profile
 | // UpdateProfileForm form for updating profile
 | ||||||
| type UpdateProfileForm struct { | type UpdateProfileForm struct { | ||||||
| 	Name     string `binding:"OmitEmpty;MaxSize(35)"` | 	Name             string `binding:"OmitEmpty;MaxSize(35)"` | ||||||
| 	FullName string `binding:"MaxSize(100)"` | 	FullName         string `binding:"MaxSize(100)"` | ||||||
| 	Email    string `binding:"Required;Email;MaxSize(254)"` | 	Email            string `binding:"Required;Email;MaxSize(254)"` | ||||||
| 	Website  string `binding:"Url;MaxSize(100)"` | 	KeepEmailPrivate bool | ||||||
| 	Location string `binding:"MaxSize(50)"` | 	Website          string `binding:"Url;MaxSize(100)"` | ||||||
|  | 	Location         string `binding:"MaxSize(50)"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Validate valideates the fields
 | // Validate valideates the fields
 | ||||||
|  |  | ||||||
|  | @ -838,6 +838,8 @@ var Service struct { | ||||||
| 	EnableReverseProxyAuth         bool | 	EnableReverseProxyAuth         bool | ||||||
| 	EnableReverseProxyAutoRegister bool | 	EnableReverseProxyAutoRegister bool | ||||||
| 	EnableCaptcha                  bool | 	EnableCaptcha                  bool | ||||||
|  | 	DefaultKeepEmailPrivate        bool | ||||||
|  | 	NoReplyAddress                 string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func newService() { | func newService() { | ||||||
|  | @ -850,6 +852,8 @@ func newService() { | ||||||
| 	Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | 	Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | ||||||
| 	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | 	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | ||||||
| 	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() | 	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() | ||||||
|  | 	Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool() | ||||||
|  | 	Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var logLevels = map[string]string{ | var logLevels = map[string]string{ | ||||||
|  |  | ||||||
|  | @ -124,6 +124,10 @@ save_config_failed = Fail to save configuration: %v | ||||||
| invalid_admin_setting = Admin account setting is invalid: %v | invalid_admin_setting = Admin account setting is invalid: %v | ||||||
| install_success = Welcome! We're glad that you chose Gitea, have fun and take care. | install_success = Welcome! We're glad that you chose Gitea, have fun and take care. | ||||||
| invalid_log_root_path = Log root path is invalid: %v | invalid_log_root_path = Log root path is invalid: %v | ||||||
|  | default_keep_email_private = Default Value for Keep Email Private | ||||||
|  | default_keep_email_private_popup = This is the default value for the visibility of the user's email address. If set to true the email address of all new users will be hidden until the user changes his setting. | ||||||
|  | no_reply_address = No-reply Address | ||||||
|  | no_reply_address_helper = Domain for the user's email address in git logs if he keeps his email address private. E.g. user 'joe' and 'noreply.example.org' will be 'joe@noreply.example.org' | ||||||
| 
 | 
 | ||||||
| [home] | [home] | ||||||
| uname_holder = Username or email | uname_holder = Username or email | ||||||
|  | @ -307,6 +311,8 @@ add_new_email = Add new email address | ||||||
| add_email = Add email | add_email = Add email | ||||||
| add_email_confirmation_sent = A new confirmation email has been sent to '%s', please check your inbox within the next %d hours to complete the confirmation process. | add_email_confirmation_sent = A new confirmation email has been sent to '%s', please check your inbox within the next %d hours to complete the confirmation process. | ||||||
| add_email_success = Your new email address was successfully added. | add_email_success = Your new email address was successfully added. | ||||||
|  | keep_email_private = Keep Email Address Private | ||||||
|  | keep_email_private_popup = Your email address will be hidden from other users if this option is set. | ||||||
| 
 | 
 | ||||||
| manage_ssh_keys = Manage SSH Keys | manage_ssh_keys = Manage SSH Keys | ||||||
| add_key = Add Key | add_key = Add Key | ||||||
|  | @ -1112,6 +1118,8 @@ config.disable_key_size_check = Disable Minimum Key Size Check | ||||||
| config.enable_captcha = Enable Captcha | config.enable_captcha = Enable Captcha | ||||||
| config.active_code_lives = Active Code Lives | config.active_code_lives = Active Code Lives | ||||||
| config.reset_password_code_lives = Reset Password Code Lives | config.reset_password_code_lives = Reset Password Code Lives | ||||||
|  | config.default_keep_email_private = Default Value for Keep Email Private | ||||||
|  | config.no_reply_address = No-reply Address | ||||||
| 
 | 
 | ||||||
| config.webhook_config = Webhook Configuration | config.webhook_config = Webhook Configuration | ||||||
| config.queue_length = Queue Length | config.queue_length = Queue Length | ||||||
|  |  | ||||||
|  | @ -111,6 +111,8 @@ func Install(ctx *context.Context) { | ||||||
| 	form.DisableRegistration = setting.Service.DisableRegistration | 	form.DisableRegistration = setting.Service.DisableRegistration | ||||||
| 	form.EnableCaptcha = setting.Service.EnableCaptcha | 	form.EnableCaptcha = setting.Service.EnableCaptcha | ||||||
| 	form.RequireSignInView = setting.Service.RequireSignInView | 	form.RequireSignInView = setting.Service.RequireSignInView | ||||||
|  | 	form.DefaultKeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate | ||||||
|  | 	form.NoReplyAddress = setting.Service.NoReplyAddress | ||||||
| 
 | 
 | ||||||
| 	auth.AssignForm(form, ctx.Data) | 	auth.AssignForm(form, ctx.Data) | ||||||
| 	ctx.HTML(200, tplInstall) | 	ctx.HTML(200, tplInstall) | ||||||
|  | @ -291,6 +293,8 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) { | ||||||
| 	cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(form.DisableRegistration)) | 	cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(form.DisableRegistration)) | ||||||
| 	cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(com.ToStr(form.EnableCaptcha)) | 	cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(com.ToStr(form.EnableCaptcha)) | ||||||
| 	cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(form.RequireSignInView)) | 	cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(form.RequireSignInView)) | ||||||
|  | 	cfg.Section("service").Key("DEFAULT_KEEP_EMAIL_PRIVATE").SetValue(com.ToStr(form.DefaultKeepEmailPrivate)) | ||||||
|  | 	cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(com.ToStr(form.NoReplyAddress)) | ||||||
| 
 | 
 | ||||||
| 	cfg.Section("").Key("RUN_MODE").SetValue("prod") | 	cfg.Section("").Key("RUN_MODE").SetValue("prod") | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -91,6 +91,7 @@ func SettingsPost(ctx *context.Context, form auth.UpdateProfileForm) { | ||||||
| 
 | 
 | ||||||
| 	ctx.User.FullName = form.FullName | 	ctx.User.FullName = form.FullName | ||||||
| 	ctx.User.Email = form.Email | 	ctx.User.Email = form.Email | ||||||
|  | 	ctx.User.KeepEmailPrivate = form.KeepEmailPrivate | ||||||
| 	ctx.User.Website = form.Website | 	ctx.User.Website = form.Website | ||||||
| 	ctx.User.Location = form.Location | 	ctx.User.Location = form.Location | ||||||
| 	if err := models.UpdateUser(ctx.User); err != nil { | 	if err := models.UpdateUser(ctx.User); err != nil { | ||||||
|  |  | ||||||
|  | @ -119,6 +119,10 @@ | ||||||
| 						<dd><i class="fa fa{{if .Service.DisableMinimumKeySizeCheck}}-check{{end}}-square-o"></i></dd>*/}} | 						<dd><i class="fa fa{{if .Service.DisableMinimumKeySizeCheck}}-check{{end}}-square-o"></i></dd>*/}} | ||||||
| 						<dt>{{.i18n.Tr "admin.config.enable_captcha"}}</dt> | 						<dt>{{.i18n.Tr "admin.config.enable_captcha"}}</dt> | ||||||
| 						<dd><i class="fa fa{{if .Service.EnableCaptcha}}-check{{end}}-square-o"></i></dd> | 						<dd><i class="fa fa{{if .Service.EnableCaptcha}}-check{{end}}-square-o"></i></dd> | ||||||
|  | 						<dt>{{.i18n.Tr "admin.config.default_keep_email_private"}}</dt> | ||||||
|  | 						<dd><i class="fa fa{{if .Service.DefaultKeepEmailPrivate}}-check{{end}}-square-o"></i></dd> | ||||||
|  | 						<dt>{{.i18n.Tr "admin.config.no_reply_address"}}</dt> | ||||||
|  | 						<dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd> | ||||||
| 						<div class="ui divider"></div> | 						<div class="ui divider"></div> | ||||||
| 						<dt>{{.i18n.Tr "admin.config.active_code_lives"}}</dt> | 						<dt>{{.i18n.Tr "admin.config.active_code_lives"}}</dt> | ||||||
| 						<dd>{{.Service.ActiveCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd> | 						<dd>{{.Service.ActiveCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd> | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
| 									{{if .Location}} | 									{{if .Location}} | ||||||
| 										<i class="octicon octicon-location"></i> {{.Location}} | 										<i class="octicon octicon-location"></i> {{.Location}} | ||||||
| 									{{end}} | 									{{end}} | ||||||
| 									{{if and $.ShowUserEmail .Email $.IsSigned}} | 									{{if and $.ShowUserEmail .Email $.IsSigned (not .KeepEmailPrivate)}} | ||||||
| 										<i class="octicon octicon-mail"></i> | 										<i class="octicon octicon-mail"></i> | ||||||
| 										<a href="mailto:{{.Email}}" rel="nofollow">{{.Email}}</a> | 										<a href="mailto:{{.Email}}" rel="nofollow">{{.Email}}</a> | ||||||
| 									{{end}} | 									{{end}} | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								templates/install.tmpl
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								templates/install.tmpl
									
									
									
									
										vendored
									
									
								
							|  | @ -206,6 +206,17 @@ | ||||||
| 									<input name="require_sign_in_view" type="checkbox" {{if .require_sign_in_view}}checked{{end}}> | 									<input name="require_sign_in_view" type="checkbox" {{if .require_sign_in_view}}checked{{end}}> | ||||||
| 								</div> | 								</div> | ||||||
| 							</div> | 							</div> | ||||||
|  | 							<div class="inline field"> | ||||||
|  | 								<div class="ui checkbox"> | ||||||
|  | 									<label class="poping up" data-content="{{.i18n.Tr "install.default_keep_email_private_popup"}}"><strong>{{.i18n.Tr "install.default_keep_email_private"}}</strong></label> | ||||||
|  | 									<input name="default_keep_email_private" type="checkbox" {{if .default_keep_email_private}}checked{{end}}> | ||||||
|  | 								</div> | ||||||
|  | 							</div> | ||||||
|  | 							<div class="inline field"> | ||||||
|  | 								<label for="no_reply_address">{{.i18n.Tr "install.no_reply_address"}}</label> | ||||||
|  | 								<input id="_no_reply_address" name="no_reply_address" value="{{.no_reply_address}}"> | ||||||
|  | 								<span class="help">{{.i18n.Tr "install.no_reply_address_helper"}}</span> | ||||||
|  | 							</div> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ | ||||||
| 							{{if .Owner.Location}} | 							{{if .Owner.Location}} | ||||||
| 								<li><i class="octicon octicon-location"></i> {{.Owner.Location}}</li> | 								<li><i class="octicon octicon-location"></i> {{.Owner.Location}}</li> | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							{{if and $.ShowUserEmail .Owner.Email .IsSigned}} | 							{{if or (and $.ShowUserEmail .Owner.Email .IsSigned) (and .Owner.Email .IsSigned (not .Owner.KeepEmailPrivate))}} | ||||||
| 								<li> | 								<li> | ||||||
| 									<i class="octicon octicon-mail"></i> | 									<i class="octicon octicon-mail"></i> | ||||||
| 									<a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a> | 									<a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a> | ||||||
|  |  | ||||||
|  | @ -27,6 +27,12 @@ | ||||||
| 							<label for="email">{{.i18n.Tr "email"}}</label> | 							<label for="email">{{.i18n.Tr "email"}}</label> | ||||||
| 							<input id="email" name="email" value="{{.SignedUser.Email}}"> | 							<input id="email" name="email" value="{{.SignedUser.Email}}"> | ||||||
| 						</div> | 						</div> | ||||||
|  | 						<div class="inline field"> | ||||||
|  | 							<div class="ui checkbox" id="keep-email-private"> | ||||||
|  | 								<label class="poping up" data-content="{{.i18n.Tr "settings.keep_email_private_popup"}}"><strong>{{.i18n.Tr "settings.keep_email_private"}}</strong></label> | ||||||
|  | 								<input name="keep_email_private" type="checkbox" {{if .SignedUser.KeepEmailPrivate}}checked{{end}}> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
| 						<div class="field {{if .Err_Website}}error{{end}}"> | 						<div class="field {{if .Err_Website}}error{{end}}"> | ||||||
| 							<label for="website">{{.i18n.Tr "settings.website"}}</label> | 							<label for="website">{{.i18n.Tr "settings.website"}}</label> | ||||||
| 							<input id="website" name="website" type="url" value="{{.SignedUser.Website}}"> | 							<input id="website" name="website" type="url" value="{{.SignedUser.Website}}"> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue