summaryrefslogtreecommitdiffstats
path: root/templates/user/auth
diff options
context:
space:
mode:
Diffstat (limited to 'templates/user/auth')
-rw-r--r--templates/user/auth/activate.tmpl61
-rw-r--r--templates/user/auth/captcha.tmpl30
-rw-r--r--templates/user/auth/change_passwd.tmpl7
-rw-r--r--templates/user/auth/change_passwd_inner.tmpl22
-rw-r--r--templates/user/auth/finalize_openid.tmpl47
-rw-r--r--templates/user/auth/forgot_passwd.tmpl39
-rw-r--r--templates/user/auth/grant.tmpl33
-rw-r--r--templates/user/auth/grant_error.tmpl16
-rw-r--r--templates/user/auth/link_account.tmpl34
-rw-r--r--templates/user/auth/oidc_wellknown.tmpl49
-rw-r--r--templates/user/auth/prohibit_login.tmpl16
-rw-r--r--templates/user/auth/reset_passwd.tmpl65
-rw-r--r--templates/user/auth/signin.tmpl10
-rw-r--r--templates/user/auth/signin_inner.tmpl70
-rw-r--r--templates/user/auth/signin_navbar.tmpl24
-rw-r--r--templates/user/auth/signin_openid.tmpl36
-rw-r--r--templates/user/auth/signup.tmpl8
-rw-r--r--templates/user/auth/signup_inner.tmpl76
-rw-r--r--templates/user/auth/signup_openid_connect.tmpl36
-rw-r--r--templates/user/auth/signup_openid_navbar.tmpl12
-rw-r--r--templates/user/auth/signup_openid_register.tmpl37
-rw-r--r--templates/user/auth/twofa.tmpl26
-rw-r--r--templates/user/auth/twofa_scratch.tmpl25
-rw-r--r--templates/user/auth/webauthn.tmpl25
-rw-r--r--templates/user/auth/webauthn_error.tmpl13
25 files changed, 817 insertions, 0 deletions
diff --git a/templates/user/auth/activate.tmpl b/templates/user/auth/activate.tmpl
new file mode 100644
index 00000000..9ae811bf
--- /dev/null
+++ b/templates/user/auth/activate.tmpl
@@ -0,0 +1,61 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user activate">
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <form class="ui form ignore-dirty tw-max-w-2xl tw-m-auto" action="{{AppSubUrl}}/user/activate" method="post">
+ {{.CsrfTokenHtml}}
+ <h2 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.active_your_account"}}
+ </h2>
+ <div class="ui attached segment">
+ {{template "base/alert" .}}
+ {{if .IsActivatePage}}
+ {{if .ServiceNotEnabled}}
+ <p class="center">{{ctx.Locale.Tr "auth.disable_register_mail"}}</p>
+ {{else if .ResendLimited}}
+ <p class="center">{{ctx.Locale.Tr "auth.resent_limit_prompt"}}</p>
+ {{else}}
+ <p>{{ctx.Locale.Tr "auth.confirmation_mail_sent_prompt" .SignedUser.Email .ActiveCodeLives}}</p>
+ {{end}}
+ {{else}}
+ {{if .NeedsPassword}}
+ <div class="required field">
+ <label for="password">{{ctx.Locale.Tr "password"}}</label>
+ <input id="password" name="password" type="password" autocomplete="off" required>
+ </div>
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "install.confirm_password"}}</button>
+ </div>
+ <input id="code" name="code" type="hidden" value="{{.Code}}">
+ {{else if .IsSendRegisterMail}}
+ <p>{{ctx.Locale.Tr "auth.confirmation_mail_sent_prompt" .Email .ActiveCodeLives}}</p>
+ {{else if .IsCodeInvalid}}
+ <p>{{ctx.Locale.Tr "auth.invalid_code"}}</p>
+ {{else if .IsPasswordInvalid}}
+ <p>{{ctx.Locale.Tr "auth.invalid_password"}}</p>
+ {{else if .ManualActivationOnly}}
+ <p class="center">{{ctx.Locale.Tr "auth.manual_activation_only"}}</p>
+ {{else}}
+ <p>{{ctx.Locale.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email}}</p>
+ <div class="divider"></div>
+ <details class="inline field">
+ <summary>{{ctx.Locale.Tr "auth.change_unconfirmed_email_summary"}}</summary>
+
+ <p>{{ctx.Locale.Tr "auth.change_unconfirmed_email"}}</p>
+ <div class="inline field">
+ <label for="email">{{ctx.Locale.Tr "email"}}</label>
+ <input id="email" name="email" type="email" autocomplete="on">
+ </div>
+ </details>
+
+ <div class="text">
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.resend_mail"}}</button>
+ </div>
+ {{end}}
+ {{end}}
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/captcha.tmpl b/templates/user/auth/captcha.tmpl
new file mode 100644
index 00000000..0e9c2b9d
--- /dev/null
+++ b/templates/user/auth/captcha.tmpl
@@ -0,0 +1,30 @@
+{{if .EnableCaptcha}}{{if eq .CaptchaType "image"}}
+ <div class="inline field">
+ {{.Captcha.CreateHTML}}
+ </div>
+ <div class="required field {{if .Err_Captcha}}error{{end}}">
+ <label for="captcha">{{ctx.Locale.Tr "captcha"}}</label>
+ <input id="captcha" name="captcha" value="{{.captcha}}" autocomplete="off">
+ </div>
+{{else if eq .CaptchaType "recaptcha"}}
+ <div class="inline field required">
+ <div id="captcha" data-captcha-type="g-recaptcha" class="g-recaptcha-style" data-sitekey="{{.RecaptchaSitekey}}"></div>
+ </div>
+ <script src='{{URLJoin .RecaptchaURL "api.js"}}'></script>
+{{else if eq .CaptchaType "hcaptcha"}}
+ <div class="inline field required">
+ <div id="captcha" data-captcha-type="h-captcha" class="h-captcha-style" data-sitekey="{{.HcaptchaSitekey}}"></div>
+ </div>
+ <script src='https://hcaptcha.com/1/api.js'></script>
+{{else if eq .CaptchaType "mcaptcha"}}
+ <div class="inline field">
+ <label></label>
+ <div class="m-captcha-style" id="mcaptcha__widget-container"></div>
+ <div id="captcha" data-captcha-type="m-captcha" data-sitekey="{{.McaptchaSitekey}}" data-instance-url="{{.McaptchaURL}}"></div>
+ </div>
+{{else if eq .CaptchaType "cfturnstile"}}
+ <div class="inline field tw-text-center">
+ <div id="captcha" data-captcha-type="cf-turnstile" data-sitekey="{{.CfTurnstileSitekey}}"></div>
+ </div>
+ <script src='https://challenges.cloudflare.com/turnstile/v0/api.js'></script>
+{{end}}{{end}}
diff --git a/templates/user/auth/change_passwd.tmpl b/templates/user/auth/change_passwd.tmpl
new file mode 100644
index 00000000..e05f46fa
--- /dev/null
+++ b/templates/user/auth/change_passwd.tmpl
@@ -0,0 +1,7 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin{{if .LinkAccountMode}} icon{{end}}">
+ <div class="ui container">
+ {{template "user/auth/change_passwd_inner" .}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/change_passwd_inner.tmpl b/templates/user/auth/change_passwd_inner.tmpl
new file mode 100644
index 00000000..601f0365
--- /dev/null
+++ b/templates/user/auth/change_passwd_inner.tmpl
@@ -0,0 +1,22 @@
+ {{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn)}}
+ {{template "base/alert" .}}
+ {{end}}
+ <h4 class="ui top attached header center">
+ {{ctx.Locale.Tr "settings.update_password"}}
+ </h4>
+ <div class="ui attached segment">
+ <form class="ui form tw-max-w-2xl tw-m-auto" action="{{.ChangePasscodeLink}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="required field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
+ <label for="password">{{ctx.Locale.Tr "password"}}</label>
+ <input id="password" name="password" type="password" value="{{.password}}" autocomplete="new-password" required>
+ </div>
+ <div class="required field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
+ <label for="retype">{{ctx.Locale.Tr "re_type"}}</label>
+ <input id="retype" name="retype" type="password" autocomplete="new-password" required>
+ </div>
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "settings.update_password"}}</button>
+ </div>
+ </form>
+ </div>
diff --git a/templates/user/auth/finalize_openid.tmpl b/templates/user/auth/finalize_openid.tmpl
new file mode 100644
index 00000000..1c1dcdb8
--- /dev/null
+++ b/templates/user/auth/finalize_openid.tmpl
@@ -0,0 +1,47 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin">
+ <div class="ui container">
+ <div class="ui grid">
+ {{template "user/auth/finalize_openid_navbar" .}}
+ <div class="twelve wide column content">
+ {{template "base/alert" .}}
+ <h4 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.login_userpass"}}
+ </h4>
+ <div class="ui attached segment">
+ <form class="ui form" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="required inline field {{if .Err_UserName}}error{{end}}">
+ <label for="user_name">{{ctx.Locale.Tr "home.uname_holder"}}</label>
+ <input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required>
+ </div>
+ <div class="required inline field {{if .Err_Password}}error{{end}}">
+ <label for="password">{{ctx.Locale.Tr "password"}}</label>
+ <input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required>
+ </div>
+ <div class="inline field">
+ <label></label>
+ <div class="ui checkbox">
+ <label>{{ctx.Locale.Tr "auth.remember_me"}}</label>
+ <input name="remember" type="checkbox">
+ </div>
+ </div>
+
+ <div class="inline field">
+ <label></label>
+ <button class="ui primary button">{{ctx.Locale.Tr "sign_in"}}</button>
+ <a href="{{AppSubUrl}}/user/forget_password">{{ctx.Locale.Tr "auth.forget_password"}}</a>
+ </div>
+ {{if .ShowRegistrationButton}}
+ <div class="inline field">
+ <label></label>
+ <a href="{{AppSubUrl}}/user/sign_up">{{ctx.Locale.Tr "auth.sign_up_now"}}</a>
+ </div>
+ {{end}}
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/forgot_passwd.tmpl b/templates/user/auth/forgot_passwd.tmpl
new file mode 100644
index 00000000..55bcf630
--- /dev/null
+++ b/templates/user/auth/forgot_passwd.tmpl
@@ -0,0 +1,39 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user forgot password">
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <form class="ui form ignore-dirty" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <h2 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.forgot_password_title"}}
+ </h2>
+ <div class="ui attached segment">
+ {{template "base/alert" .}}
+ {{if .IsResetSent}}
+ <p>{{ctx.Locale.Tr "auth.reset_password_mail_sent_prompt" .Email .ResetPwdCodeLives}}</p>
+ {{else if .IsResetRequest}}
+ <div class="required field {{if .Err_Email}}error{{end}}">
+ <label for="email">{{ctx.Locale.Tr "email"}}</label>
+ <input id="email" name="email" type="email" value="{{.Email}}" autofocus required>
+ </div>
+ <div class="divider"></div>
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.send_reset_mail"}}</button>
+ </div>
+ {{else if .IsResetDisable}}
+ <p class="center">
+ {{if $.IsAdmin}}
+ {{ctx.Locale.Tr "auth.disable_forgot_password_mail_admin"}}
+ {{else}}
+ {{ctx.Locale.Tr "auth.disable_forgot_password_mail"}}
+ {{end}}
+ </p>
+ {{else if .ResendLimited}}
+ <p class="center">{{ctx.Locale.Tr "auth.resent_limit_prompt"}}</p>
+ {{end}}
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/grant.tmpl b/templates/user/auth/grant.tmpl
new file mode 100644
index 00000000..a18a3bd2
--- /dev/null
+++ b/templates/user/auth/grant.tmpl
@@ -0,0 +1,33 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content ui one column stackable center aligned page grid oauth2-authorize-application-box">
+ <div class="column seven wide">
+ <div class="ui middle centered raised segments">
+ <h3 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.authorize_title" .Application.Name}}
+ </h3>
+ <div class="ui attached segment">
+ {{template "base/alert" .}}
+ <p>
+ <b>{{ctx.Locale.Tr "auth.authorize_application_description"}}</b><br>
+ {{ctx.Locale.Tr "auth.authorize_application_created_by" .ApplicationCreatorLinkHTML}}
+ </p>
+ </div>
+ <div class="ui attached segment">
+ <p>{{ctx.Locale.Tr "auth.authorize_redirect_notice" .ApplicationRedirectDomainHTML}}</p>
+ </div>
+ <div class="ui attached segment">
+ <form method="post" action="{{AppSubUrl}}/login/oauth/grant">
+ {{.CsrfTokenHtml}}
+ <input type="hidden" name="client_id" value="{{.Application.ClientID}}">
+ <input type="hidden" name="state" value="{{.State}}">
+ <input type="hidden" name="scope" value="{{.Scope}}">
+ <input type="hidden" name="nonce" value="{{.Nonce}}">
+ <input type="hidden" name="redirect_uri" value="{{.RedirectURI}}">
+ <button type="submit" id="authorize-app" name="granted" value="true" class="ui red inline button">{{ctx.Locale.Tr "auth.authorize_application"}}</button>
+ <button type="submit" name="granted" value="false" class="ui basic primary inline button">{{ctx.Locale.Tr "cancel"}}</button>
+ </form>
+ </div>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/grant_error.tmpl b/templates/user/auth/grant_error.tmpl
new file mode 100644
index 00000000..b2e07796
--- /dev/null
+++ b/templates/user/auth/grant_error.tmpl
@@ -0,0 +1,16 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content ui one column stackable center aligned page grid oauth2-authorize-application-box {{if .IsRepo}}repository{{end}}">
+ {{if .IsRepo}}{{template "repo/header" .}}{{end}}
+ <div class="column seven wide">
+ <div class="ui middle centered raised segments">
+ <h1 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.authorization_failed"}}
+ </h1>
+ <h3 class="ui attached segment">{{.Error.ErrorDescription}}</h3>
+ <div class="ui attached segment">
+ <p>{{ctx.Locale.Tr "auth.authorization_failed_desc"}}</p>
+ </div>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/link_account.tmpl b/templates/user/auth/link_account.tmpl
new file mode 100644
index 00000000..8dd49ccd
--- /dev/null
+++ b/templates/user/auth/link_account.tmpl
@@ -0,0 +1,34 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user link-account">
+ <overflow-menu class="ui secondary pointing tabular top attached borderless menu secondary-nav">
+ <div class="overflow-menu-items tw-justify-center">
+ <!-- TODO handle .ShowRegistrationButton once other login bugs are fixed -->
+ {{if not .AllowOnlyInternalRegistration}}
+ <a class="item {{if not .user_exists}}active{{end}}"
+ data-tab="auth-link-signup-tab">
+ {{ctx.Locale.Tr "auth.oauth_signup_tab"}}
+ </a>
+ {{end}}
+ <a class="item {{if .user_exists}}active{{end}}"
+ data-tab="auth-link-signin-tab">
+ {{ctx.Locale.Tr "auth.oauth_signin_tab"}}
+ </a>
+ </div>
+ </overflow-menu>
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <div class="ui tab {{if not .user_exists}}active{{end}}"
+ data-tab="auth-link-signup-tab">
+ {{template "user/auth/signup_inner" .}}
+ </div>
+ <div class="ui tab {{if .user_exists}}active{{end}}"
+ data-tab="auth-link-signin-tab">
+ <div class="ui user signin container icon">
+ {{template "user/auth/signin_inner" .}}
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+{{template "base/footer" .}}
diff --git a/templates/user/auth/oidc_wellknown.tmpl b/templates/user/auth/oidc_wellknown.tmpl
new file mode 100644
index 00000000..54bb4a76
--- /dev/null
+++ b/templates/user/auth/oidc_wellknown.tmpl
@@ -0,0 +1,49 @@
+{
+ "issuer": "{{AppUrl | JSEscape}}",
+ "authorization_endpoint": "{{AppUrl | JSEscape}}login/oauth/authorize",
+ "token_endpoint": "{{AppUrl | JSEscape}}login/oauth/access_token",
+ "jwks_uri": "{{AppUrl | JSEscape}}login/oauth/keys",
+ "userinfo_endpoint": "{{AppUrl | JSEscape}}login/oauth/userinfo",
+ "introspection_endpoint": "{{AppUrl | JSEscape}}login/oauth/introspect",
+ "response_types_supported": [
+ "code",
+ "id_token"
+ ],
+ "id_token_signing_alg_values_supported": [
+ "{{.SigningKey.SigningMethod.Alg | JSEscape}}"
+ ],
+ "subject_types_supported": [
+ "public"
+ ],
+ "scopes_supported": [
+ "openid",
+ "profile",
+ "email",
+ "groups"
+ ],
+ "claims_supported": [
+ "aud",
+ "exp",
+ "iat",
+ "iss",
+ "sub",
+ "name",
+ "preferred_username",
+ "profile",
+ "picture",
+ "website",
+ "locale",
+ "updated_at",
+ "email",
+ "email_verified",
+ "groups"
+ ],
+ "code_challenge_methods_supported": [
+ "plain",
+ "S256"
+ ],
+ "grant_types_supported": [
+ "authorization_code",
+ "refresh_token"
+ ]
+}
diff --git a/templates/user/auth/prohibit_login.tmpl b/templates/user/auth/prohibit_login.tmpl
new file mode 100644
index 00000000..962ddfa9
--- /dev/null
+++ b/templates/user/auth/prohibit_login.tmpl
@@ -0,0 +1,16 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user activate">
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <form class="ui form tw-max-w-2xl tw-m-auto">
+ <h2 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.prohibit_login"}}
+ </h2>
+ <div class="ui attached segment">
+ <p>{{ctx.Locale.Tr "auth.prohibit_login_desc"}}</p>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/reset_passwd.tmpl b/templates/user/auth/reset_passwd.tmpl
new file mode 100644
index 00000000..f8303fee
--- /dev/null
+++ b/templates/user/auth/reset_passwd.tmpl
@@ -0,0 +1,65 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user reset password">
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <form class="ui form ignore-dirty" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <input name="code" type="hidden" value="{{.Code}}">
+ <h2 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.reset_password"}}
+ </h2>
+ <div class="ui attached segment">
+ {{template "base/alert" .}}
+ {{if .user_email}}
+ <div class="inline field">
+ <label for="user_name">{{ctx.Locale.Tr "email"}}</label>
+ <input id="user_name" type="text" value="{{.user_email}}" disabled>
+ </div>
+ {{end}}
+ {{if .IsResetForm}}
+ <div class="required field {{if .Err_Password}}error{{end}}">
+ <label for="password">{{ctx.Locale.Tr "settings.new_password"}}</label>
+ <input id="password" name="password" type="password" value="{{.password}}" autocomplete="new-password" autofocus required>
+ </div>
+ {{if not .user_signed_in}}
+ <div class="inline field">
+ <div class="ui checkbox">
+ <label>{{ctx.Locale.Tr "auth.remember_me"}}</label>
+ <input name="remember" type="checkbox">
+ </div>
+ </div>
+ {{end}}
+ {{if .has_two_factor}}
+ <h4 class="ui dividing header">
+ {{ctx.Locale.Tr "twofa"}}
+ </h4>
+ <div class="ui warning visible message">{{ctx.Locale.Tr "settings.twofa_is_enrolled"}}</div>
+ {{if .scratch_code}}
+ <div class="required inline field {{if .Err_Token}}error{{end}}">
+ <label for="token">{{ctx.Locale.Tr "auth.scratch_code"}}</label>
+ <input id="token" name="token" type="text" autocomplete="off" autofocus required>
+ </div>
+ <input type="hidden" name="scratch_code" value="true">
+ {{else}}
+ <div class="required field {{if .Err_Passcode}}error{{end}}">
+ <label for="passcode">{{ctx.Locale.Tr "passcode"}}</label>
+ <input id="passcode" name="passcode" type="number" autocomplete="off" autofocus required>
+ </div>
+ {{end}}
+ {{end}}
+ <div class="divider"></div>
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.reset_password_helper"}}</button>
+ {{if and .has_two_factor (not .scratch_code)}}
+ <a href="?code={{.Code}}&scratch_code=true">{{ctx.Locale.Tr "auth.use_scratch_code"}}</a>
+ {{end}}
+ </div>
+ {{else}}
+ <p class="center">{{ctx.Locale.Tr "auth.invalid_code_forgot_password" (printf "%s/user/forgot_password" AppSubUrl)}}</p>
+ {{end}}
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/signin.tmpl b/templates/user/auth/signin.tmpl
new file mode 100644
index 00000000..b0e9ce8c
--- /dev/null
+++ b/templates/user/auth/signin.tmpl
@@ -0,0 +1,10 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin{{if .LinkAccountMode}} icon{{end}}">
+ {{template "user/auth/signin_navbar" .}}
+ <div class="ui middle very relaxed page grid">
+ <div class="ui container column fluid">
+ {{template "user/auth/signin_inner" .}}
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/signin_inner.tmpl b/templates/user/auth/signin_inner.tmpl
new file mode 100644
index 00000000..9872096f
--- /dev/null
+++ b/templates/user/auth/signin_inner.tmpl
@@ -0,0 +1,70 @@
+{{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn)}}
+{{template "base/alert" .}}
+{{end}}
+<h4 class="ui top attached header center">
+ {{if .LinkAccountMode}}
+ {{ctx.Locale.Tr "auth.oauth_signin_title"}}
+ {{else}}
+ {{ctx.Locale.Tr "auth.login_userpass"}}
+ {{end}}
+</h4>
+<div class="ui attached segment">
+ <form class="ui form tw-max-w-2xl tw-m-auto" action="{{.SignInLink}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="required field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
+ <label for="user_name">{{ctx.Locale.Tr "home.uname_holder"}}</label>
+ <input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required>
+ </div>
+ {{if or (not .DisablePassword) .LinkAccountMode}}
+ <div class="required field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
+ <label for="password">{{ctx.Locale.Tr "password"}}</label>
+ <input id="password" name="password" type="password" value="{{.password}}" autocomplete="current-password" required>
+ </div>
+ {{end}}
+ {{if not .LinkAccountMode}}
+ <div class="inline field">
+ <div class="ui checkbox">
+ <label>{{ctx.Locale.Tr "auth.remember_me"}}</label>
+ <input name="remember" type="checkbox">
+ </div>
+ </div>
+ {{end}}
+
+ {{template "user/auth/captcha" .}}
+
+ <div class="field">
+ <button class="ui primary button">
+ {{if .LinkAccountMode}}
+ {{ctx.Locale.Tr "auth.oauth_signin_submit"}}
+ {{else}}
+ {{ctx.Locale.Tr "sign_in"}}
+ {{end}}
+ </button>
+ <a href="{{AppSubUrl}}/user/forgot_password">{{ctx.Locale.Tr "auth.forgot_password"}}</a>
+ </div>
+
+ {{if .ShowRegistrationButton}}
+ <div class="field">
+ <a href="{{AppSubUrl}}/user/sign_up">{{ctx.Locale.Tr "auth.sign_up_now"}}</a>
+ </div>
+ {{end}}
+
+ {{if .OAuth2Providers}}
+ <div class="divider divider-text">
+ {{ctx.Locale.Tr "sign_in_or"}}
+ </div>
+ <div id="oauth2-login-navigator" class="tw-py-1">
+ <div class="tw-flex tw-flex-col tw-justify-center">
+ <div id="oauth2-login-navigator-inner" class="tw-flex tw-flex-col tw-flex-wrap tw-items-center tw-gap-2">
+ {{range $provider := .OAuth2Providers}}
+ <a class="{{$provider.Name}} ui button tw-flex tw-items-center tw-justify-center tw-py-2 tw-w-full oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.DisplayName}}">
+ {{$provider.IconHTML 28}}
+ {{ctx.Locale.Tr "sign_in_with_provider" $provider.DisplayName}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </form>
+</div>
diff --git a/templates/user/auth/signin_navbar.tmpl b/templates/user/auth/signin_navbar.tmpl
new file mode 100644
index 00000000..01b994b9
--- /dev/null
+++ b/templates/user/auth/signin_navbar.tmpl
@@ -0,0 +1,24 @@
+{{if or .EnableOpenIDSignIn .EnableSSPI}}
+<overflow-menu class="ui secondary pointing tabular top attached borderless menu navbar secondary-nav">
+ <div class="overflow-menu-items tw-justify-center">
+ <a class="{{if .PageIsLogin}}active {{end}}item" rel="nofollow" href="{{AppSubUrl}}/user/login">
+ {{ctx.Locale.Tr "auth.tab_signin"}}
+ </a>
+ <a class="{{if .PageIsSignUp}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/sign_up">
+ {{ctx.Locale.Tr "auth.tab_signup"}}
+ </a>
+ {{if .EnableOpenIDSignIn}}
+ <a class="{{if .PageIsLoginOpenID}}active {{end}}item" rel="nofollow" href="{{AppSubUrl}}/user/login/openid">
+ {{svg "fontawesome-openid"}}
+ &nbsp;{{ctx.Locale.Tr "auth.tab_openid"}}
+ </a>
+ {{end}}
+ {{if .EnableSSPI}}
+ <a class="item" rel="nofollow" href="{{AppSubUrl}}/user/login?auth_with_sspi=1">
+ {{svg "fontawesome-windows"}}
+ &nbsp;SSPI
+ </a>
+ {{end}}
+ </div>
+</overflow-menu>
+{{end}}
diff --git a/templates/user/auth/signin_openid.tmpl b/templates/user/auth/signin_openid.tmpl
new file mode 100644
index 00000000..c1f392dc
--- /dev/null
+++ b/templates/user/auth/signin_openid.tmpl
@@ -0,0 +1,36 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin openid">
+ {{template "user/auth/signin_navbar" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+ <h4 class="ui top attached header center">
+ {{svg "fontawesome-openid"}}
+ OpenID
+ </h4>
+ <div class="ui attached segment">
+ <form class="ui form tw-m-auto" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="inline field">
+ {{ctx.Locale.Tr "auth.openid_signin_desc"}}
+ </div>
+ <div class="required field {{if .Err_OpenID}}error{{end}}">
+ <label for="openid">
+ {{svg "fontawesome-openid"}}
+ OpenID URI
+ </label>
+ <input id="openid" name="openid" value="{{.openid}}" autofocus required>
+ </div>
+ <div class="inline field">
+ <div class="ui checkbox">
+ <label>{{ctx.Locale.Tr "auth.remember_me"}}</label>
+ <input name="remember" type="checkbox">
+ </div>
+ </div>
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "sign_in"}}</button>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/signup.tmpl b/templates/user/auth/signup.tmpl
new file mode 100644
index 00000000..f238413c
--- /dev/null
+++ b/templates/user/auth/signup.tmpl
@@ -0,0 +1,8 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin{{if .LinkAccountMode}} icon{{end}}">
+ {{template "user/auth/signin_navbar" .}}
+ <div class="ui middle very relaxed page grid">
+ {{template "user/auth/signup_inner" .}}
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl
new file mode 100644
index 00000000..bdb691d8
--- /dev/null
+++ b/templates/user/auth/signup_inner.tmpl
@@ -0,0 +1,76 @@
+<div class="ui container column fluid{{if .LinkAccountMode}} icon{{end}}">
+ <h4 class="ui top attached header center">
+ {{if .LinkAccountMode}}
+ {{ctx.Locale.Tr "auth.oauth_signup_title"}}
+ {{else}}
+ {{ctx.Locale.Tr "sign_up"}}
+ {{end}}
+ </h4>
+ <div class="ui attached segment">
+ <form class="ui form tw-max-w-2xl tw-m-auto" action="{{.SignUpLink}}" method="post">
+ {{.CsrfTokenHtml}}
+ {{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister)}}
+ {{template "base/alert" .}}
+ {{end}}
+ {{if .DisableRegistration}}
+ <p>{{ctx.Locale.Tr "auth.disable_register_prompt"}}</p>
+ {{else}}
+ <div class="required field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
+ <label for="user_name">{{ctx.Locale.Tr "username"}}</label>
+ <input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required>
+ </div>
+ <div class="required field {{if .Err_Email}}error{{end}}">
+ <label for="email">{{ctx.Locale.Tr "email"}}</label>
+ <input id="email" name="email" type="email" value="{{.email}}" required>
+ </div>
+
+ {{if not .DisablePassword}}
+ <div class="required field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
+ <label for="password">{{ctx.Locale.Tr "password"}}</label>
+ <input id="password" name="password" type="password" value="{{.password}}" autocomplete="new-password" required>
+ </div>
+ <div class="required field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
+ <label for="retype">{{ctx.Locale.Tr "re_type"}}</label>
+ <input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="new-password" required>
+ </div>
+ {{end}}
+
+ {{template "user/auth/captcha" .}}
+
+ <div class="inline field">
+ <button class="ui primary button">
+ {{if .LinkAccountMode}}
+ {{ctx.Locale.Tr "auth.oauth_signup_submit"}}
+ {{else}}
+ {{ctx.Locale.Tr "auth.create_new_account"}}
+ {{end}}
+ </button>
+ </div>
+
+ {{if not .LinkAccountMode}}
+ <div class="inline field">
+ <a href="{{AppSubUrl}}/user/login">{{ctx.Locale.Tr "auth.register_helper_msg"}}</a>
+ </div>
+ {{end}}
+ {{end}}
+
+ {{if .OAuth2Providers}}
+ <div class="divider divider-text">
+ {{ctx.Locale.Tr "sign_in_or"}}
+ </div>
+ <div id="oauth2-login-navigator" class="tw-py-1">
+ <div class="tw-flex tw-flex-col tw-justify-center">
+ <div id="oauth2-login-navigator-inner" class="tw-flex tw-flex-col tw-flex-wrap tw-items-center tw-gap-2">
+ {{range $provider := .OAuth2Providers}}
+ <a class="{{$provider.Name}} ui button tw-flex tw-items-center tw-justify-center tw-py-2 tw-w-full oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.DisplayName}}">
+ {{$provider.IconHTML 28}}
+ {{ctx.Locale.Tr "sign_in_with_provider" $provider.DisplayName}}
+ </a>
+ {{end}}
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </form>
+ </div>
+</div>
diff --git a/templates/user/auth/signup_openid_connect.tmpl b/templates/user/auth/signup_openid_connect.tmpl
new file mode 100644
index 00000000..e4b79363
--- /dev/null
+++ b/templates/user/auth/signup_openid_connect.tmpl
@@ -0,0 +1,36 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signup">
+ {{template "user/auth/signup_openid_navbar" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+ <h4 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.openid_connect_title"}}
+ </h4>
+ <div class="ui attached segment">
+ <p>
+ {{ctx.Locale.Tr "auth.openid_connect_desc"}}
+ </p>
+ <form class="ui form" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="required inline field {{if .Err_UserName}}error{{end}}">
+ <label for="user_name">{{ctx.Locale.Tr "home.uname_holder"}}</label>
+ <input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required>
+ </div>
+ <div class="required inline field {{if .Err_Password}}error{{end}}">
+ <label for="password">{{ctx.Locale.Tr "password"}}</label>
+ <input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required>
+ </div>
+ <div class="inline field">
+ <label for="openid">OpenID URI</label>
+ <input id="openid" value="{{.OpenID}}" readonly>
+ </div>
+ <div class="inline field">
+ <label></label>
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.openid_connect_submit"}}</button>
+ <a href="{{AppSubUrl}}/user/forgot_password">{{ctx.Locale.Tr "auth.forgot_password"}}</a>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/signup_openid_navbar.tmpl b/templates/user/auth/signup_openid_navbar.tmpl
new file mode 100644
index 00000000..89068ddd
--- /dev/null
+++ b/templates/user/auth/signup_openid_navbar.tmpl
@@ -0,0 +1,12 @@
+<overflow-menu class="ui secondary pointing tabular top attached borderless menu secondary-nav">
+ <div class="overflow-menu-items tw-justify-center">
+ <a class="{{if .PageIsOpenIDConnect}}active {{end}}item" href="{{AppSubUrl}}/user/openid/connect">
+ {{ctx.Locale.Tr "auth.openid_connect_title"}}
+ </a>
+ {{if and .EnableOpenIDSignUp (not .AllowOnlyInternalRegistration)}}
+ <a class="{{if .PageIsOpenIDRegister}}active {{end}}item" href="{{AppSubUrl}}/user/openid/register">
+ {{ctx.Locale.Tr "auth.openid_register_title"}}
+ </a>
+ {{end}}
+ </div>
+</overflow-menu>
diff --git a/templates/user/auth/signup_openid_register.tmpl b/templates/user/auth/signup_openid_register.tmpl
new file mode 100644
index 00000000..c017a0e6
--- /dev/null
+++ b/templates/user/auth/signup_openid_register.tmpl
@@ -0,0 +1,37 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signup">
+ {{template "user/auth/signup_openid_navbar" .}}
+ <div class="ui container">
+ {{template "base/alert" .}}
+ <h4 class="ui top attached header">
+ {{ctx.Locale.Tr "auth.openid_register_title"}}
+ </h4>
+ <div class="ui attached segment">
+ <p class="tw-max-w-2xl tw-mx-auto">
+ {{ctx.Locale.Tr "auth.openid_register_desc"}}
+ </p>
+ <form class="ui form" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <div class="required field {{if .Err_UserName}}error{{end}}">
+ <label for="user_name">{{ctx.Locale.Tr "username"}}</label>
+ <input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required>
+ </div>
+ <div class="required field {{if .Err_Email}}error{{end}}">
+ <label for="email">{{ctx.Locale.Tr "email"}}</label>
+ <input id="email" name="email" type="email" value="{{.email}}" required>
+ </div>
+
+ {{template "user/auth/captcha" .}}
+
+ <div class="field">
+ <label for="openid">OpenID URI</label>
+ <input id="openid" value="{{.OpenID}}" readonly>
+ </div>
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.create_new_account"}}</button>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/twofa.tmpl b/templates/user/auth/twofa.tmpl
new file mode 100644
index 00000000..d2452391
--- /dev/null
+++ b/templates/user/auth/twofa.tmpl
@@ -0,0 +1,26 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin">
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <form class="ui form tw-max-w-2xl tw-m-auto" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <h3 class="ui top attached header">
+ {{ctx.Locale.Tr "twofa"}}
+ </h3>
+ <div class="ui attached segment">
+ {{template "base/alert" .}}
+ <div class="required field">
+ <label for="passcode">{{ctx.Locale.Tr "passcode"}}</label>
+ <input id="passcode" name="passcode" type="text" autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" autofocus required>
+ </div>
+
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.verify"}}</button>
+ <a href="{{AppSubUrl}}/user/two_factor/scratch">{{ctx.Locale.Tr "auth.use_scratch_code"}}</a>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/twofa_scratch.tmpl b/templates/user/auth/twofa_scratch.tmpl
new file mode 100644
index 00000000..23ad77f2
--- /dev/null
+++ b/templates/user/auth/twofa_scratch.tmpl
@@ -0,0 +1,25 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin">
+ <div class="ui middle very relaxed page grid">
+ <div class="column">
+ <form class="ui form tw-max-w-2xl tw-m-auto" action="{{.Link}}" method="post">
+ {{.CsrfTokenHtml}}
+ <h3 class="ui top attached header">
+ {{ctx.Locale.Tr "twofa_scratch"}}
+ </h3>
+ <div class="ui attached segment">
+ {{template "base/alert" .}}
+ <div class="required field">
+ <label for="token">{{ctx.Locale.Tr "auth.scratch_code"}}</label>
+ <input id="token" name="token" type="text" autocomplete="off" autofocus required>
+ </div>
+
+ <div class="inline field">
+ <button class="ui primary button">{{ctx.Locale.Tr "auth.verify"}}</button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/webauthn.tmpl b/templates/user/auth/webauthn.tmpl
new file mode 100644
index 00000000..1b847653
--- /dev/null
+++ b/templates/user/auth/webauthn.tmpl
@@ -0,0 +1,25 @@
+{{template "base/head" .}}
+<div role="main" aria-label="{{.Title}}" class="page-content user signin webauthn-prompt">
+ <div class="ui page grid">
+ <div class="column center aligned">
+ {{template "user/auth/webauthn_error" .}}
+ <h3 class="ui top attached header">{{ctx.Locale.Tr "twofa"}}</h3>
+ <div class="ui attached segment">
+ {{svg "octicon-key" 56}}
+ <h3>{{ctx.Locale.Tr "webauthn_insert_key"}}</h3>
+ {{template "base/alert" .}}
+ <p>{{ctx.Locale.Tr "webauthn_sign_in"}}</p>
+ </div>
+ <div class="ui attached segment tw-flex tw-items-center tw-justify-center tw-gap-1 tw-py-2">
+ <div class="is-loading tw-w-[40px] tw-h-[40px]"></div>
+ {{ctx.Locale.Tr "webauthn_press_button"}}
+ </div>
+ {{if .HasTwoFactor}}
+ <div class="ui attached segment">
+ <a href="{{AppSubUrl}}/user/two_factor">{{ctx.Locale.Tr "webauthn_use_twofa"}}</a>
+ </div>
+ {{end}}
+ </div>
+ </div>
+</div>
+{{template "base/footer" .}}
diff --git a/templates/user/auth/webauthn_error.tmpl b/templates/user/auth/webauthn_error.tmpl
new file mode 100644
index 00000000..511ff7c2
--- /dev/null
+++ b/templates/user/auth/webauthn_error.tmpl
@@ -0,0 +1,13 @@
+<div id="webauthn-error" class="ui negative message tw-hidden">
+ <div class="header">{{ctx.Locale.Tr "webauthn_error"}}</div>
+ <div id="webauthn-error-msg" class="tw-pt-2"></div>
+ <div class="tw-hidden">
+ <div data-webauthn-error-msg="browser">{{ctx.Locale.Tr "webauthn_unsupported_browser"}}</div>
+ <div data-webauthn-error-msg="unknown">{{ctx.Locale.Tr "webauthn_error_unknown"}}</div>
+ <div data-webauthn-error-msg="insecure">{{ctx.Locale.Tr "webauthn_error_insecure"}}</div>
+ <div data-webauthn-error-msg="unable-to-process">{{ctx.Locale.Tr "webauthn_error_unable_to_process"}}</div>
+ <div data-webauthn-error-msg="duplicated">{{ctx.Locale.Tr "webauthn_error_duplicated"}}</div>
+ <div data-webauthn-error-msg="empty">{{ctx.Locale.Tr "webauthn_error_empty"}}</div>
+ <div data-webauthn-error-msg="timeout">{{ctx.Locale.Tr "webauthn_error_timeout"}}</div>
+ </div>
+</div>