mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 20:21:47 +01:00 
			
		
		
		
	Make captcha and password optional for external accounts (#6606)
This commit is contained in:
		
							parent
							
								
									337d6915ff
								
							
						
					
					
						commit
						62d6127f1b
					
				| @ -216,6 +216,9 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. | |||||||
|    Requires `Mailer` to be enabled. |    Requires `Mailer` to be enabled. | ||||||
| - `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create | - `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create | ||||||
|    accounts for users. |    accounts for users. | ||||||
|  | - `REQUIRE_EXTERNAL_REGISTRATION_PASSWORD`: **false**: Enable this to force externally created | ||||||
|  |    accounts (via GitHub, OpenID Connect, etc) to create a password. Warning: enabling this will | ||||||
|  |    decrease security, so you should only enable it if you know what you're doing. | ||||||
| - `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page. | - `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page. | ||||||
| - `ENABLE_NOTIFY_MAIL`: **false**: Enable this to send e-mail to watchers of a repository when | - `ENABLE_NOTIFY_MAIL`: **false**: Enable this to send e-mail to watchers of a repository when | ||||||
|    something happens, like creating issues. Requires `Mailer` to be enabled. |    something happens, like creating issues. Requires `Mailer` to be enabled. | ||||||
| @ -225,6 +228,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. | |||||||
| - `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a | - `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a | ||||||
|    provided email rather than a generated email. |    provided email rather than a generated email. | ||||||
| - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration. | - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration. | ||||||
|  | - `REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA`: **false**: Enable this to force captcha validation | ||||||
|  |    even for External Accounts (i.e. GitHub, OpenID Connect, etc). You must `ENABLE_CAPTCHA` also. | ||||||
| - `CAPTCHA_TYPE`: **image**: \[image, recaptcha\] | - `CAPTCHA_TYPE`: **image**: \[image, recaptcha\] | ||||||
| - `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha. | - `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha. | ||||||
| - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. | - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. | ||||||
| @ -419,7 +424,7 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` | |||||||
| 
 | 
 | ||||||
| ## Metrics (`metrics`) | ## Metrics (`metrics`) | ||||||
| 
 | 
 | ||||||
| - `ENABLED`: **false**: Enables /metrics endpoint for prometheus.  | - `ENABLED`: **false**: Enables /metrics endpoint for prometheus. | ||||||
| - `TOKEN`: **\<empty\>**: You need to specify the token, if you want to include in the authorization the metrics . The same token need to be used in prometheus parameters `bearer_token` or `bearer_token_file`. | - `TOKEN`: **\<empty\>**: You need to specify the token, if you want to include in the authorization the metrics . The same token need to be used in prometheus parameters `bearer_token` or `bearer_token_file`. | ||||||
| 
 | 
 | ||||||
| ## API (`api`) | ## API (`api`) | ||||||
|  | |||||||
| @ -79,7 +79,7 @@ func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) bindin | |||||||
| type RegisterForm struct { | type RegisterForm struct { | ||||||
| 	UserName           string `binding:"Required;AlphaDashDot;MaxSize(40)"` | 	UserName           string `binding:"Required;AlphaDashDot;MaxSize(40)"` | ||||||
| 	Email              string `binding:"Required;Email;MaxSize(254)"` | 	Email              string `binding:"Required;Email;MaxSize(254)"` | ||||||
| 	Password           string `binding:"Required;MaxSize(255)"` | 	Password           string `binding:"MaxSize(255)"` | ||||||
| 	Retype             string | 	Retype             string | ||||||
| 	GRecaptchaResponse string `form:"g-recaptcha-response"` | 	GRecaptchaResponse string `form:"g-recaptcha-response"` | ||||||
| } | } | ||||||
| @ -129,6 +129,7 @@ func (f *MustChangePasswordForm) Validate(ctx *macaron.Context, errs binding.Err | |||||||
| // SignInForm form for signing in with user/password | // SignInForm form for signing in with user/password | ||||||
| type SignInForm struct { | type SignInForm struct { | ||||||
| 	UserName string `binding:"Required;MaxSize(254)"` | 	UserName string `binding:"Required;MaxSize(254)"` | ||||||
|  | 	// TODO remove required from password for SecondFactorAuthentication | ||||||
| 	Password string `binding:"Required;MaxSize(255)"` | 	Password string `binding:"Required;MaxSize(255)"` | ||||||
| 	Remember bool | 	Remember bool | ||||||
| } | } | ||||||
|  | |||||||
| @ -27,6 +27,8 @@ var Service struct { | |||||||
| 	EnableReverseProxyAutoRegister          bool | 	EnableReverseProxyAutoRegister          bool | ||||||
| 	EnableReverseProxyEmail                 bool | 	EnableReverseProxyEmail                 bool | ||||||
| 	EnableCaptcha                           bool | 	EnableCaptcha                           bool | ||||||
|  | 	RequireExternalRegistrationCaptcha      bool | ||||||
|  | 	RequireExternalRegistrationPassword     bool | ||||||
| 	CaptchaType                             string | 	CaptchaType                             string | ||||||
| 	RecaptchaSecret                         string | 	RecaptchaSecret                         string | ||||||
| 	RecaptchaSitekey                        string | 	RecaptchaSitekey                        string | ||||||
| @ -61,6 +63,8 @@ func newService() { | |||||||
| 	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | 	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | ||||||
| 	Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool() | 	Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool() | ||||||
| 	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false) | 	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false) | ||||||
|  | 	Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha) | ||||||
|  | 	Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool() | ||||||
| 	Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha) | 	Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha) | ||||||
| 	Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("") | 	Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("") | ||||||
| 	Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("") | 	Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("") | ||||||
|  | |||||||
| @ -697,9 +697,10 @@ func oAuth2UserLoginCallback(loginSource *models.LoginSource, request *http.Requ | |||||||
| 
 | 
 | ||||||
| // LinkAccount shows the page where the user can decide to login or create a new account | // LinkAccount shows the page where the user can decide to login or create a new account | ||||||
| func LinkAccount(ctx *context.Context) { | func LinkAccount(ctx *context.Context) { | ||||||
|  | 	ctx.Data["DisablePassword"] = !setting.Service.RequireExternalRegistrationCaptcha || setting.Service.AllowOnlyExternalRegistration | ||||||
| 	ctx.Data["Title"] = ctx.Tr("link_account") | 	ctx.Data["Title"] = ctx.Tr("link_account") | ||||||
| 	ctx.Data["LinkAccountMode"] = true | 	ctx.Data["LinkAccountMode"] = true | ||||||
| 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha | ||||||
| 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
| 	ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | 	ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | ||||||
| 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| @ -746,10 +747,11 @@ func LinkAccount(ctx *context.Context) { | |||||||
| 
 | 
 | ||||||
| // LinkAccountPostSignIn handle the coupling of external account with another account using signIn | // LinkAccountPostSignIn handle the coupling of external account with another account using signIn | ||||||
| func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { | func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { | ||||||
|  | 	ctx.Data["DisablePassword"] = setting.Service.AllowOnlyExternalRegistration | ||||||
| 	ctx.Data["Title"] = ctx.Tr("link_account") | 	ctx.Data["Title"] = ctx.Tr("link_account") | ||||||
| 	ctx.Data["LinkAccountMode"] = true | 	ctx.Data["LinkAccountMode"] = true | ||||||
| 	ctx.Data["LinkAccountModeSignIn"] = true | 	ctx.Data["LinkAccountModeSignIn"] = true | ||||||
| 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha | ||||||
| 	ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | 	ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | ||||||
| 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
| 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| @ -824,10 +826,13 @@ func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { | |||||||
| 
 | 
 | ||||||
| // LinkAccountPostRegister handle the creation of a new account for an external account using signUp | // LinkAccountPostRegister handle the creation of a new account for an external account using signUp | ||||||
| func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { | func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { | ||||||
|  | 	// TODO Make insecure passwords optional for local accounts also, | ||||||
|  | 	//      once email-based Second-Factor Auth is available | ||||||
|  | 	ctx.Data["DisablePassword"] = !setting.Service.RequireExternalRegistrationCaptcha || setting.Service.AllowOnlyExternalRegistration | ||||||
| 	ctx.Data["Title"] = ctx.Tr("link_account") | 	ctx.Data["Title"] = ctx.Tr("link_account") | ||||||
| 	ctx.Data["LinkAccountMode"] = true | 	ctx.Data["LinkAccountMode"] = true | ||||||
| 	ctx.Data["LinkAccountModeRegister"] = true | 	ctx.Data["LinkAccountModeRegister"] = true | ||||||
| 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha | ||||||
| 	ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | 	ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | ||||||
| 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
| 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| @ -854,14 +859,18 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ImageCaptcha && !cpt.VerifyReq(ctx.Req) { | 	if setting.Service.EnableCaptcha && setting.Service.RequireExternalRegistrationCaptcha { | ||||||
| 		ctx.Data["Err_Captcha"] = true | 		var valid bool | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form) | 		switch setting.Service.CaptchaType { | ||||||
| 		return | 		case setting.ImageCaptcha: | ||||||
| 	} | 			valid = cpt.VerifyReq(ctx.Req) | ||||||
|  | 		case setting.ReCaptcha: | ||||||
|  | 			valid, _ = recaptcha.Verify(form.GRecaptchaResponse) | ||||||
|  | 		default: | ||||||
|  | 			ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ReCaptcha { |  | ||||||
| 		valid, _ := recaptcha.Verify(form.GRecaptchaResponse) |  | ||||||
| 		if !valid { | 		if !valid { | ||||||
| 			ctx.Data["Err_Captcha"] = true | 			ctx.Data["Err_Captcha"] = true | ||||||
| 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form) | 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form) | ||||||
| @ -869,15 +878,24 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (len(strings.TrimSpace(form.Password)) > 0 || len(strings.TrimSpace(form.Retype)) > 0) && form.Password != form.Retype { | 	if setting.Service.AllowOnlyExternalRegistration || !setting.Service.RequireExternalRegistrationPassword { | ||||||
| 		ctx.Data["Err_Password"] = true | 		// In models.User an empty password is classed as not set, so we set form.Password to empty. | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplLinkAccount, &form) | 		// Eventually the database should be changed to indicate "Second Factor"-enabled accounts | ||||||
| 		return | 		// (accounts that do not introduce the security vulnerabilities of a password). | ||||||
| 	} | 		// If a user decides to circumvent second-factor security, and purposefully create a password, | ||||||
| 	if len(strings.TrimSpace(form.Password)) > 0 && len(form.Password) < setting.MinPasswordLength { | 		// they can still do so using the "Recover Account" option. | ||||||
| 		ctx.Data["Err_Password"] = true | 		form.Password = "" | ||||||
| 		ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplLinkAccount, &form) | 	} else { | ||||||
| 		return | 		if (len(strings.TrimSpace(form.Password)) > 0 || len(strings.TrimSpace(form.Retype)) > 0) && form.Password != form.Retype { | ||||||
|  | 			ctx.Data["Err_Password"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplLinkAccount, &form) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		if len(strings.TrimSpace(form.Password)) > 0 && len(form.Password) < setting.MinPasswordLength { | ||||||
|  | 			ctx.Data["Err_Password"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplLinkAccount, &form) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	loginSource, err := models.GetActiveOAuth2LoginSourceByName(gothUser.(goth.User).Provider) | 	loginSource, err := models.GetActiveOAuth2LoginSourceByName(gothUser.(goth.User).Provider) | ||||||
| @ -1000,14 +1018,18 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ImageCaptcha && !cpt.VerifyReq(ctx.Req) { | 	if setting.Service.EnableCaptcha { | ||||||
| 		ctx.Data["Err_Captcha"] = true | 		var valid bool | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUp, &form) | 		switch setting.Service.CaptchaType { | ||||||
| 		return | 		case setting.ImageCaptcha: | ||||||
| 	} | 			valid = cpt.VerifyReq(ctx.Req) | ||||||
|  | 		case setting.ReCaptcha: | ||||||
|  | 			valid, _ = recaptcha.Verify(form.GRecaptchaResponse) | ||||||
|  | 		default: | ||||||
|  | 			ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ReCaptcha { |  | ||||||
| 		valid, _ := recaptcha.Verify(form.GRecaptchaResponse) |  | ||||||
| 		if !valid { | 		if !valid { | ||||||
| 			ctx.Data["Err_Captcha"] = true | 			ctx.Data["Err_Captcha"] = true | ||||||
| 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUp, &form) | 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUp, &form) | ||||||
|  | |||||||
| @ -357,19 +357,23 @@ func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.Si | |||||||
| 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| 	ctx.Data["OpenID"] = oid | 	ctx.Data["OpenID"] = oid | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ImageCaptcha && !cpt.VerifyReq(ctx.Req) { | 	if setting.Service.EnableCaptcha { | ||||||
| 		ctx.Data["Err_Captcha"] = true | 		var valid bool | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUpOID, &form) | 		switch setting.Service.CaptchaType { | ||||||
| 		return | 		case setting.ImageCaptcha: | ||||||
| 	} | 			valid = cpt.VerifyReq(ctx.Req) | ||||||
| 
 | 		case setting.ReCaptcha: | ||||||
| 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ReCaptcha { | 			err := ctx.Req.ParseForm() | ||||||
| 		err := ctx.Req.ParseForm() | 			if err != nil { | ||||||
| 		if err != nil { | 				ctx.ServerError("", err) | ||||||
| 			ctx.ServerError("", err) | 				return | ||||||
|  | 			} | ||||||
|  | 			valid, _ = recaptcha.Verify(form.GRecaptchaResponse) | ||||||
|  | 		default: | ||||||
|  | 			ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		valid, _ := recaptcha.Verify(form.GRecaptchaResponse) | 
 | ||||||
| 		if !valid { | 		if !valid { | ||||||
| 			ctx.Data["Err_Captcha"] = true | 			ctx.Data["Err_Captcha"] = true | ||||||
| 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUpOID, &form) | 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUpOID, &form) | ||||||
|  | |||||||
| @ -15,10 +15,12 @@ | |||||||
| 				<label for="user_name">{{.i18n.Tr "home.uname_holder"}}</label> | 				<label for="user_name">{{.i18n.Tr "home.uname_holder"}}</label> | ||||||
| 				<input id="user_name" name="user_name" value="{{.user_name}}" autofocus required> | 				<input id="user_name" name="user_name" value="{{.user_name}}" autofocus required> | ||||||
| 			</div> | 			</div> | ||||||
|  | 			{{if not .DisablePassword}} | ||||||
| 			<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}"> | 			<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}"> | ||||||
| 				<label for="password">{{.i18n.Tr "password"}}</label> | 				<label for="password">{{.i18n.Tr "password"}}</label> | ||||||
| 				<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required> | 				<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required> | ||||||
| 			</div> | 			</div> | ||||||
|  | 			{{end}} | ||||||
| 			{{if not .LinkAccountMode}} | 			{{if not .LinkAccountMode}} | ||||||
| 			<div class="inline field"> | 			<div class="inline field"> | ||||||
| 				<label></label> | 				<label></label> | ||||||
|  | |||||||
| @ -25,14 +25,17 @@ | |||||||
| 							<label for="email">{{.i18n.Tr "email"}}</label> | 							<label for="email">{{.i18n.Tr "email"}}</label> | ||||||
| 							<input id="email" name="email" type="email" value="{{.email}}" required> | 							<input id="email" name="email" type="email" value="{{.email}}" required> | ||||||
| 						</div> | 						</div> | ||||||
| 						<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | 
 | ||||||
| 							<label for="password">{{.i18n.Tr "password"}}</label> | 						{{if not .DisablePassword}} | ||||||
| 							<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required> | 							<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | ||||||
| 						</div> | 								<label for="password">{{.i18n.Tr "password"}}</label> | ||||||
| 						<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | 								<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required> | ||||||
| 							<label for="retype">{{.i18n.Tr "re_type"}}</label> | 							</div> | ||||||
| 							<input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="off" required> | 							<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | ||||||
| 						</div> | 								<label for="retype">{{.i18n.Tr "re_type"}}</label> | ||||||
|  | 								<input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="off" required> | ||||||
|  | 							</div> | ||||||
|  | 						{{end}} | ||||||
| 						{{if and .EnableCaptcha (eq .CaptchaType "image")}} | 						{{if and .EnableCaptcha (eq .CaptchaType "image")}} | ||||||
| 							<div class="inline field"> | 							<div class="inline field"> | ||||||
| 								<label></label> | 								<label></label> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user