Auth screen (templates & handlers) translation

This commit is contained in:
Martin Salamon
2021-08-23 19:10:21 +02:00
committed by Denis Arh
parent ca86a36a5d
commit ddef6ed5b4
31 changed files with 220 additions and 190 deletions
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" set . "activeNav" "clients" }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Authorized clients</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "authorized-clients.template.title" }}</h1>
<form
method="POST"
class="clearfix"
@@ -14,7 +14,7 @@
<div class="p-3">
<div class="text-primary font-weight-bold">{{ .Name }}</div>
<div>
Authorized on
{{ tr "authorized-clients.template.authorized" }}
<time
datetime="{{ .ConfirmedAt | date "2006-01-02T15:04:05Z07:00" }}"
>
@@ -27,12 +27,12 @@
value="{{ .ID }}"
class="btn btn-sm btn-danger"
>
Revoke access
{{ tr "authorized-clients.template.button.revoke-access" }}
</button>
</div>
{{ else }}
<div class="text-center m-3 mb-5">
<i>No authorized clients found</i>
<i>{{ tr "authorized-clients.template.no-auth-clients" }}</i>
</div>
{{ end }}
</form>
+11 -11
View File
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" set . "activeNav" "security" }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Change your password</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "change-password.template.title" }}</h1>
<form
method="POST"
action="{{ links.ChangePassword }}"
@@ -14,20 +14,20 @@
{{ end }}
<div class="mb-3">
<label>
E-mail *
{{ tr "change-password.template.form.email.label" }}
</label>
<input
type="email"
class="form-control"
name="email"
readonly
placeholder="email@domain.ltd"
placeholder="{{ tr "change-password.template.form.email.placeholder" }}"
value="{{ .user.Email }}"
aria-label="Email">
aria-label="{{ tr "change-password.template.form.email.aria-label" }}">
</div>
<div class="mb-3">
<label>
Old Password *
{{ tr "change-password.template.form.old-password.label" }}
</label>
<input
type="password"
@@ -35,12 +35,12 @@
class="form-control"
name="oldPassword"
autocomplete="current-password"
placeholder="Enter your old password"
aria-label="Old password">
placeholder="{{ tr "change-password.template.form.old-password.placeholder" }}"
aria-label="{{ tr "change-password.template.form.old-password.aria-label" }}">
</div>
<div class="mb-3">
<label>
New Password *
{{ tr "change-password.template.form.new-password.label" }}
</label>
<input
type="password"
@@ -48,11 +48,11 @@
class="form-control"
name="newPassword"
autocomplete="new-password"
placeholder="Enter your new password"
aria-label="New password">
placeholder="{{ tr "change-password.template.form.new-password.placeholder" }}"
aria-label="{{ tr "change-password.template.form.new-password.aria-label" }}">
</div>
<div class="text-right">
<button class="btn btn-primary btn-block btn-lg" type="submit">Change your password</button>
<button class="btn btn-primary btn-block btn-lg" type="submit">{{ tr "change-password.template.form.button.change-password" }}</button>
</div>
</form>
</div>
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Internal error</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "error-internal.template.title" }}</h1>
<div class="text-danger mb-4 font-weight-bold p-3" role="alert">
{{ .error }}
</div>
+1 -9
View File
@@ -1,19 +1,11 @@
</main>
{{ template "inc_toasts.html.tpl" .alerts }}
{{ if .user }}
<div class="position-absolute user text-white m-2">
You're logged-in as
<a class="font-weight-bold text-white" href="{{ links.Profile }}">{{ coalesce .user.Name .user.Handle .user.Email }}</a>
|
<a class="font-weight-bold text-white" href="{{ links.Logout }}">Logout</a>
</div>
{{ end }}
<div class="footer col text-center position-absolute mb-4">
<a href="https://cortezaproject.org/" target="_blank" class="text-white mr-2">cortezaproject.org</a>
<a href="https://github.com/cortezaproject/" target="_blank" class="text-white ml-2">GitHub</a>
</div>
<i class="p-1 small text-white position-absolute version mr-3 mb-3">
version {{ version }}
{{ tr "inc_footer.version" "version" version }}
</small>
</body>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
@@ -17,6 +17,14 @@
</title>
</head>
<body style="background: url({{ links.Assets }}/background.jpeg) no-repeat top;background-size: cover;background-attachment: fixed;">
{{ if .user }}
<div class="position-absolute user text-white m-2">
{{ tr "inc_header.logged-in-as" }}
<a class="font-weight-bold text-white" href="{{ links.Profile }}">{{ coalesce .user.Name .user.Handle .user.Email }}</a>
|
<a class="font-weight-bold text-white" href="{{ links.Logout }}">{{ tr "inc_header.logout" }}</a>
</div>
{{ end }}
<main class="auth mt-sm-5 pt-md-5">
<div class="card">
{{ template "inc_nav.html.tpl" . }}
+5 -5
View File
@@ -11,23 +11,23 @@
{{ if and .user .client }}
<div class="py-1 px-3">
<a href="{{ links.OAuth2AuthorizeClient }}" class="text-danger">
Finalize the authorization of {{ .client.Name }}
{{ tr "inc_nav.template.authorize-client" }} {{ .client.Name }}
<i class="bi bi-chevron-double-right"></i>
</a>
</div>
{{ else if .user }}
<ul class="nav ml-1 d-flex justify-content-around">
<li class="nav-item {{ if eq $activeNav "profile" }}active{{ end }}">
<a class="nav-link" href="{{ links.Profile }}">Your profile</a>
<a class="nav-link" href="{{ links.Profile }}">{{ tr "inc_nav.template.class.your-profile" }}</a>
</li>
<li class="nav-item {{ if eq $activeNav "security" }}active{{ end }}">
<a class="nav-link" href="{{ links.Security }}">Security</a>
<a class="nav-link" href="{{ links.Security }}">{{ tr "inc_nav.template.class.security" }}</a>
</li>
<li class="nav-item {{ if eq $activeNav "sessions" }}active{{ end }}">
<a class="nav-link" href="{{ links.Sessions }}">Login sessions</a>
<a class="nav-link" href="{{ links.Sessions }}">{{ tr "inc_nav.template.class.login-session" }}</a>
</li>
<li class="nav-item {{ if eq $activeNav "clients" }}active{{ end }}">
<a class="nav-link" href="{{ links.AuthorizedClients }}">Authorized clients</a>
<a class="nav-link" href="{{ links.AuthorizedClients }}">{{ tr "inc_nav.template.class.authorized-clients" }}</a>
</li>
</ul>
{{ end }}
+13 -13
View File
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Log in</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "login.template.title" }}</h1>
{{ if .settings.LocalEnabled }}
<form
method="POST"
@@ -15,31 +15,31 @@
{{ end }}
<div class="mb-3">
<label>
E-mail *
{{ tr "login.template.form.email.label" }} *
</label>
<input
type="email"
class="form-control"
name="email"
required
placeholder="email@domain.ltd"
placeholder="{{ tr "login.template.form.email.placeholder" }}"
value="{{ if .form }}{{ .form.email }}{{ end }}"
autocomplete="username"
aria-label="Email">
aria-label="{{ tr "login.template.form.email.label" }}">
</div>
{{ if not .form.splitCredentialsCheck }}
<div class="mb-3">
<label>
Password *
{{ tr "login.template.form.password.label" }} *
</label>
<input
type="password"
required
class="form-control"
name="password"
placeholder="Password"
placeholder="{{ tr "login.template.form.password.placeholder" }}"
autocomplete="current-password"
aria-label="Password">
aria-label="{{ tr "login.template.form.password.labels" }}">
</div>
<div class="row">
<div class="col text-right">
@@ -49,13 +49,13 @@
value="true"
type="submit"
>
Log in and remember me
{{ tr "login.template.form.button.login-and-remember" }}
</button>
<button
class="btn btn-light btn-block"
type="submit"
>
Log in
{{ tr "login.template.form.button.login" }}
</button>
</div>
</div>
@@ -68,7 +68,7 @@
value="true"
type="submit"
>
Continue
{{ tr "login.template.form.button.continue" }}
</button>
</div>
</div>
@@ -77,12 +77,12 @@
<div class="row text-center">
{{ if .settings.PasswordResetEnabled }}
<div class="col cols-6 mb-5">
<a href="{{ links.RequestPasswordReset }}">Forgot your password?</a>
<a href="{{ links.RequestPasswordReset }}">{{ tr "login.template.links.request-password-reset" }}</a>
</div>
{{ end }}
{{ if .settings.SignupEnabled }}
<div class="col cols-6 mb-5">
<a href="{{ links.Signup }}">Create a new account</a>
<a href="{{ links.Signup }}">{{ tr "login.template.links.signup" }}</a>
</div>
{{ end }}
</div>
@@ -92,7 +92,7 @@
{{ range .providers }}
<a href="{{ links.External }}/{{ .Handle }}" class="btn btn-light btn-block btn-lg mb-2 text-dark">
<i class="bi bi-{{ .Icon }} mr-1"></i>
Login with {{ coalesce .Label .Handle }}
{{ tr "login.template.external.login-with" "idp" (coalesce .Label .Handle) }}
</a>
{{ end }}
</div>
+1 -1
View File
@@ -7,7 +7,7 @@
</div>
{{ else }}
<div class="text-dark font-weight-bold" role="primary">
Log out successful.
{{ tr "logout.log-out" }}
</div>
{{ end }}
@@ -1,13 +1,13 @@
{{ template "inc_header.html.tpl" set . "hideNav" true }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Disable two-factor authentication with TOTP</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "mfa_totp_disable.template.title" }}</h1>
<form
class="p-3"
method="POST"
action="{{ links.MfaTotpDisable }}"
>
Disable by entering existing code.
{{ tr "mfa_totp_disable.template.form.title" }}
{{ if .form.error }}
<div class="pt-3 text-danger font-weight-bold" role="alert">
@@ -37,7 +37,7 @@
value="true"
type="submit"
>
Remove
{{ tr "mfa_totp_disable.template.form.button" }}
</button>
</form>
</div>
+12 -15
View File
@@ -4,8 +4,7 @@
{{ if .enforced }}
<p class="p-3 text-danger mb-0 font-weight-bold">
TOTP multi factor authentication is enforced by Corteza administrator.
Please configure it right away.
{{ tr "mfa_totp.template.paragraph" }}
</p>
{{ end }}
@@ -21,7 +20,7 @@
method="POST"
action="{{ links.MfaTotpNewSecret }}"
>
Complete the configuration by entering code from the authenticator application:
{{ tr "mfa_totp.template.form.title-2" }}
{{ if .form.error }}
<div class="alert alert-danger" role="alert">
@@ -51,34 +50,32 @@
value="true"
type="submit"
>
Submit
{{ tr "mfa_totp.template.form.button" }}
</button>
</form>
</div>
<div class="col-12 col-sm-6">
<p class="text-justify">
Corteza uses time based one time passwords (TOTP) as one of the
underlying technologies for two-factor authentication.
Use one of the applications listed below and type in the secret or scan the QR code.
{{ tr "mfa_totp.template.form.paragraph-one" }}
</p>
<p>
This will enable additional security for your account.
{{ tr "mfa_totp.template.form.paragraph-two" }}
</p>
<p>
You can use one of the following applications:
{{ tr "mfa_totp.template.form.paragraph-three" }}
</p>
<ul>
<li>
<a target="_blank" href="https://lastpass.com/auth/">LastPass Authenticator</a>
<a target="_blank" href="https://lastpass.com/auth/">{{ tr "mfa_totp.template.form.ul-links.auth" }}</a>
</li>
<li>
Google Authenticator in <br />
<a target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Android</a>
or
<a target="_blank" href="https://apps.apple.com/us/app/google-authenticator/id388497605">App Store</a>
{{ tr "mfa_totp.template.form.ul-links.text" }} <br />
<a target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">{{ tr "mfa_totp.template.form.ul-links.android" }}</a>
{{ tr "mfa_totp.template.form.ul-links.or" }}
<a target="_blank" href="https://apps.apple.com/us/app/google-authenticator/id388497605">{{ tr "mfa_totp.template.form.ul-links.store" }}</a>
</li>
<li>
<a target="_blank" href="https://authy.com">Authy</a>
<a target="_blank" href="https://authy.com">{{ tr "mfa_totp.template.form.ul-links.authy" }}</a>
</li>
</ul>
</div>
+12 -12
View File
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" set . "hideNav" true }}
<div class="card-body p-0 mb-2">
<h1 class="h4 card-title p-3 border-bottom">Multi-factor authentication</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "mfa.template.title" }}</h1>
{{ if .emailOtpPending }}
<form
@@ -8,7 +8,7 @@
method="POST"
action="{{ links.Mfa }}"
>
<h5>Check your inbox and enter the received code</h5>
<h5>{{ tr "mfa.template.form-1.title" }}</h5>
{{ if .form.emailOtpError }}
<div class="text-danger my-4 font-weight-bold" role="alert">
@@ -27,10 +27,10 @@
maxlength="6"
minlength="6"
aria-required="true"
placeholder="000 000"
placeholder="{{ tr "mfa.template.input-group-my-3.placeholder" }}"
autocomplete="off"
style="letter-spacing:5px;font-size:20px;"
aria-label="Code">
aria-label="{{ tr "mfa.template.input-group-my-3.aria-label" }}">
</div>
<button
@@ -39,7 +39,7 @@
value="verifyEmailOtp"
type="submit"
>
Verify
{{ tr "mfa.buttons.verify" }}
</button>
<a
@@ -48,12 +48,12 @@
name="action"
value="resendEmailOtp"
>
Resend
{{ tr "mfa.buttons.resend" }}
</a>
</form>
{{ else if not .emailOtpDisabled }}
<p class="p-3 mb-0">
<i class="bi bi-check-circle text-success h5 mr-1"></i> Email OTP confirmed
<i class="bi bi-check-circle text-success h5 mr-1"></i> {{ tr "mfa.paragraph-1" }}
</p>
{{ end }}
@@ -63,7 +63,7 @@
method="POST"
action="{{ links.Mfa }}"
>
<h5>Check your TOTP application and enter the code you received</h5>
<h5>{{ tr "mfa.template.form-2.title" }}</h5>
{{ if .form.totpError }}
<div class="alert alert-danger" role="alert">
@@ -82,10 +82,10 @@
maxlength="6"
minlength="6"
aria-required="true"
placeholder="000 000"
placeholder="{{ tr "mfa.template.input-group-my-3.placeholder" }}"
autocomplete="off"
style="letter-spacing:5px;font-size:20px;"
aria-label="Code">
aria-label="{{ tr "mfa.template.input-group-my-3.aria-label" }}">
</div>
<button
@@ -94,12 +94,12 @@
name="action"
value="verifyTotp"
>
Verify
{{ tr "mfa.buttons.verify" }}
</button>
</form>
{{ else if not .totpDisabled }}
<p class="p-3 mb-0">
<i class="bi bi-check-circle text-success h5 mr-1"></i> TOTP confirmed
<i class="bi bi-check-circle text-success h5 mr-1"></i> {{ tr "mfa.paragraph-2" }}
</p>
{{ end }}
</div>
@@ -7,7 +7,7 @@
</div>
{{ end }}
<h1 class="h4 card-title p-3 border-bottom">Authorize "{{ coalesce .client.Name }}"</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "oauth2_authorize_client.template.title" }} "{{ coalesce .client.Name }}"</h1>
<form
action="{{ links.OAuth2AuthorizeClient }}"
@@ -16,10 +16,10 @@
>
{{ .csrfField }}
<p>
Hello {{ coalesce .user.Name .user.Handle .user.Email }},
{{ tr "oauth2_authorize_client.template.form.greeting-paragraph" }} {{ coalesce .user.Name .user.Handle .user.Email }},
</p>
<p>
<b>{{ .client.Name }}</b> would like to perform actions on this Corteza server on your behalf.
<b>{{ .client.Name }}</b> {{ tr "oauth2_authorize_client.template.form.question-for-client" }}
</p>
<p class="text-center">
@@ -30,7 +30,7 @@
class="btn btn-{{ if .disabled }}secondary{{ else }}primary{{ end }} btn-lg m-2"
style="width:250px;"
>
Allow
{{ tr "oauth2_authorize_client.template.form.button-allow" }}
</button>
<button
type="submit"
@@ -38,11 +38,11 @@
class="btn btn-danger btn-lg m-2"
style="width:250px;"
>
Deny
{{ tr "oauth2_authorize_client.template.form.button-deny" }}
</button>
</p>
<div class="text-center">
If this is a mistake, please <a href="{{ links.Logout }}">log out</a>.
{{ tr "oauth2_authorize_client.template.form.mistake" }} <a href="{{ links.Logout }}">{{ tr "oauth2_authorize_client.template.form.log-out-link" }}</a>.
</div>
</form>
@@ -1,13 +1,13 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Password reset requested</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "password_reset_requested.template.title" }}</h1>
<div class="p-3" role="alert">
If the email you entered is found in our database, you'll receive a password reset link to your inbox in a few moments.
{{ tr "password_reset_requested.template.alert" }}
</div>
<div class="text-center my-3">
<a href="{{ links.Signup }}">Create new account</a>
<a href="{{ links.Signup }}">{{ tr "password_reset_requested.template.new-account-link" }}</a>
or
<a href="{{ links.Login }}">Log in</a>
<a href="{{ links.Login }}">{{ tr "password_reset_requested.template.login" }}</a>
</div>
</div>
{{ template "inc_footer.html.tpl" . }}
@@ -1,13 +1,13 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Confirm your email</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "pending_email_confirmation.template.title" }}</h1>
<div class="p-3" role="alert">
You should receive email confirmation link to your inbox in a few moments.
{{ tr "pending_email_confirmation.template.alert" }}
</div>
<div class="text-center my-3">
<a href="{{ links.Signup }}">Create new account</a>
<a href="{{ links.Signup }}">{{ tr "pending_email_confirmation.template.new-acc-link" }}</a>
or
<a href="{{ links.Login }}">Log in</a>
<a href="{{ links.Login }}">{{ tr "pending_email_confirmation.template.login" }}</a>
</div>
</div>
{{ template "inc_footer.html.tpl" . }}
+12 -12
View File
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" set . "activeNav" "profile" }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Your profile</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "profile.template.title" }}</h1>
<form
method="POST"
action="{{ links.Profile }}"
@@ -15,50 +15,50 @@
{{ end }}
<div class="mb-3">
<label for="profileFormEmail">Email</label>
<label for="profileFormEmail">{{ tr "profile.template.form.email.label" }}</label>
<input
type="email"
class="form-control"
name="email"
id="profileFormEmail"
placeholder="email@domain.ltd"
placeholder="{{ tr "profile.template.form.email.placeholder" }}"
autocomplete="username"
readonly
value="{{ .form.email }}"
aria-label="Email">
aria-label="{{ tr "profile.template.form.email.aria-label" }}">
<div>
{{ if .emailConfirmationRequired }}
<div class="form-text text-danger">
Email is not verified, <a href="{{ links.PendingEmailConfirmation }}?resend">resend confirmation link.</a>
{{ tr "profile.template.form.text-danger-1" }} <a href="{{ links.PendingEmailConfirmation }}?resend">{{ tr "profile.template.form.text-danger-2" }}</a>
</div>
{{ end }}
</div>
</div>
<div class="mb-3">
<label for="profileFormName">Full name</label>
<label for="profileFormName">{{ tr "profile.template.form.name.label" }}</label>
<input
type="text"
class="form-control"
name="name"
id="profileFormName"
placeholder="Your full name"
placeholder="{{ tr "profile.template.form.name.placeholder" }}"
value="{{ .form.name }}"
autocomplete="name"
aria-label="Full name">
aria-label="{{ tr "profile.template.form.name.aria-label" }}">
</div>
<div class="mb-3">
<label for="profileFormHandle">Handle</label>
<label for="profileFormHandle">{{ tr "profile.template.form.handle.label" }}</label>
<input
type="text"
class="form-control handle-mask"
name="handle"
id="profileFormHandle"
placeholder="Short name, nickname or handle"
placeholder="{{ tr "profile.template.form.handle.placeholder" }}"
value="{{ .form.handle }}"
autocomplete="handle"
aria-label="Handle">
aria-label="{{ tr "profile.template.form.handle.aria-label" }}">
</div>
<div>
@@ -66,7 +66,7 @@
type="submit"
class="btn btn-primary btn-block btn-lg"
>
Update profile
{{ tr "profile.template.form.button" }}
</button>
</div>
</form>
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Request password reset link</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "request_password_reset.template.title" }}</h1>
<form
method="POST"
action="{{ links.RequestPasswordReset }}"
@@ -14,26 +14,26 @@
{{ end }}
<div class="mb-3">
<label>
E-mail *
{{ tr "request_password_reset.template.form.email.label" }}
</label>
<input
type="email"
class="form-control"
name="email"
required
placeholder="email@domain.ltd"
placeholder="{{ tr "request_password_reset.template.form.email.placeholder" }}"
autocomplete="username"
value="{{ if .form }}{{ .form.email }}{{ end }}"
aria-label="Email">
aria-label="{{ tr "request_password_reset.template.form.email.aria-label" }}">
</div>
<div class="text-right">
<button class="btn btn-primary btn-block btn-lg" type="submit">Request password reset link via email</button>
<button class="btn btn-primary btn-block btn-lg" type="submit">{{ tr "request_password_reset.template.form.button" }}</button>
</div>
</form>
<div class="text-center my-3">
<a href="{{ links.Signup }}">Create new account</a>
or
<a href="{{ links.Login }}">Log in</a>
<a href="{{ links.Signup }}">{{ tr "request_password_reset.template.new-acc-link" }}</a>
{{ tr "request_password_reset.template.or" }}
<a href="{{ links.Login }}">{{ tr "request_password_reset.template.login" }}</a>
</div>
</div>
{{ template "inc_footer.html.tpl" . }}
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Reset your password</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "reset_password.template.title" }}</h1>
<form
method="POST"
action="{{ links.ResetPassword }}"
@@ -14,20 +14,20 @@
{{ end }}
<div class="mb-3">
<label>
E-mail *
{{ tr "reset_password.template.form.email.label" }}
</label>
<input
type="email"
class="form-control"
name="email"
readonly
placeholder="email@domain.ltd"
placeholder="{{ tr "reset_password.template.form.email.placeholder" }}"
value="{{ .user.Email }}"
aria-label="Email">
aria-label="{{ tr "reset_password.template.form.email.aria-label" }}">
</div>
<div class="mb-3">
<label>
New Password *
{{ tr "reset_password.template.form.new-password.label" }}
</label>
<input
type="password"
@@ -35,11 +35,11 @@
class="form-control"
name="password"
autocomplete="new-password"
placeholder="Set new password"
aria-label="Set new password">
placeholder="{{ tr "reset_password.template.form.new-password.placeholder" }}"
aria-label="{{ tr "reset_password.template.form.new-password.aria-label" }}">
</div>
<div class="text-right">
<button class="btn btn-primary btn-block btn-lg" type="submit">Change your password</button>
<button class="btn btn-primary btn-block btn-lg" type="submit">{{ tr "reset_password.template.form.button.change-password" }}</button>
</div>
</form>
</div>
+15 -15
View File
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" set . "activeNav" "security" }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Security</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "security.template.title" }}</h1>
<form
method="POST"
action="{{ links.Security }}"
@@ -8,19 +8,19 @@
>
{{ if .settings.LocalEnabled }}
<h5>Password</h5>
<a href="{{ links.ChangePassword }}">Change your password</a>
<h5>{{ tr "security.template.form.title" }}</h5>
<a href="{{ links.ChangePassword }}">{{ tr "security.template.form.passw-change" }}</a>
{{ end }}
<hr />
<div>
{{ .csrfField }}
<h5>Multi-factor authentication</h5>
<h5>{{ tr "security.template.security.title" }}</h5>
{{ if or .settings.MultiFactor.TOTP.Enabled .settings.MultiFactor.EmailOTP.Enabled }}
{{ if .settings.MultiFactor.TOTP.Enabled }}
<div class="py-4">
<h6>Additional security with mobile app (time-based one-time-password)</h6>
<h6>{{ tr "security.template.security.description" }}</h6>
<div class="row">
<div class="col-10 pt-2">
{{ if .totpEnforced }}
@@ -29,18 +29,18 @@
<i class="bi bi-exclamation-circle-fill text-danger h5 mr-1"></i>
{{ end }}
{{ if .totpEnforced }}
Configured and required on login.
{{ tr "security.template.security.req-login" }}
{{ else }}
Currently disabled.
{{ tr "security.template.security.disable" }}
{{ end }}
</div>
<div class="col-md-2 col-sm-12">
{{ if .totpEnforced }}
{{ if not .settings.MultiFactor.TOTP.Enforced }}
<button name="action" value="disableTOTP" class="btn btn-danger float-right">Disable</button>
<button name="action" value="disableTOTP" class="btn btn-danger float-right">{{ tr "security.template.button.disable" }}</button>
{{ end }}
{{ else }}
<button name="action" value="configureTOTP" class="btn btn-primary float-right">Configure</button>
<button name="action" value="configureTOTP" class="btn btn-primary float-right">{{ tr "security.template.button.configure" }}</button>
{{ end }}
</div>
</div>
@@ -49,7 +49,7 @@
{{ if .settings.MultiFactor.EmailOTP.Enabled }}
<div class="py-4">
<h6>Additional security with one-time-password over email</h6>
<h6>{{ tr "security.template.aditional-security.title" }}</h6>
<div class="row">
<div class="col-10 pt-2">
{{ if .emailOtpEnforced }}
@@ -58,18 +58,18 @@
<i class="bi bi-exclamation-circle-fill text-danger h5 mr-1"></i>
{{ end }}
{{ if .emailOtpEnforced }}
Enabled and required on login.
{{ tr "security.template.aditional-security.email-otp-enforced" }}
{{ else }}
Currently disabled.
{{ tr "security.template.aditional-security.disable" }}
{{ end }}
</div>
<div class="col-md-2 col-sm-12">
{{ if .emailOtpEnforced }}
{{ if not .settings.MultiFactor.EmailOTP.Enforced }}
<button name="action" value="disableEmailOTP" class="btn btn-danger float-right">Disable</button>
<button name="action" value="disableEmailOTP" class="btn btn-danger float-right">{{ tr "security.template.button.disable" }}</button>
{{ end }}
{{ else }}
<button name="action" value="enableEmailOTP" class="btn btn-primary float-right">Enable</button>
<button name="action" value="enableEmailOTP" class="btn btn-primary float-right">{{ tr "security.template.button.enable" }}</button>
{{ end }}
</div>
@@ -78,7 +78,7 @@
{{ end }}
{{ else }}
<div class="mb-4 font-italic" role="alert">
All MFA methods are currently disabled. Ask your administrator to enable them.
{{ tr "security.template.alert" }}
</div>
{{ end }}
</div>
+13 -13
View File
@@ -1,7 +1,7 @@
{{ template "inc_header.html.tpl" set . "activeNav" "sessions" }}
<div class="card-body p-0">
<div class="card-title p-3 border-bottom">
<h4 class="card-title d-inline">Your sessions</h4>
<h4 class="card-title d-inline">{{ tr "session.template.title" }}</h4>
{{ if .sessions}}
<button
type="submit"
@@ -9,7 +9,7 @@
value="true"
class="btn btn-sm btn-danger float-right"
>
Delete all sessions
{{ tr "session.template.button.delete-all" }}
</button>
{{ end }}
</div>
@@ -23,7 +23,7 @@
{{ range .sessions}}
<div class="mb-3 border-bottom">
{{ if .Current }}
<h5>Current session</h5>
<h5>{{ tr "session.template.form.title" }}</h5>
{{ end }}
{{ if not .Current }}
<button
@@ -32,37 +32,37 @@
value="{{ .ID }}"
class="btn btn-sm btn-link text-danger float-right"
>
Delete this session
{{ tr "session.template.button.delete-this" }}
</button>
{{ end }}
<label class="mb-0 d-block">Authorized on</label>
<label class="mb-0 d-block">{{ tr "session.template.form.label-auth" }}</label>
<p class="w-75 d-inline-block">
<time datetime="{{ .CreatedAt }}">{{ .CreatedAt | date "Mon, 02 Jan 2006 15:04 MST" }}</time>
</p>
<label class="mb-0 d-block">IP Address</label>
<label class="mb-0 d-block">{{ tr "session.template.form.label-IP" }}</label>
<p class="w-75 d-inline-block">{{ .RemoteAddr }}</p>
{{ if .SameRemoteAddr}}
<span class="badge badge-light float-right">This machine</span>
<span class="badge badge-light float-right">{{ tr "session.template.form.span-machine" }}</span>
{{ end }}
<label class="mb-0 d-block">Expires</label>
<label class="mb-0 d-block">{{ tr "session.template.form.label-expire.title" }}</label>
<p class="w-75 d-inline-block">
<time datetime="{{ .ExpiresAt }}">{{ .ExpiresAt | date "Mon, 02 Jan 2006 15:04 MST" }}</time>
</p>
{{ if .Expired }}
<span class="badge badge-warning float-right">expired</span>
<span class="badge badge-warning float-right">{{ tr "session.template.form.label-expire.expired" }}</span>
{{ else if eq .ExpiresIn 0 }}
<span class="badge badge-warning float-right">today</span>
<span class="badge badge-warning float-right">{{ tr "session.template.form.label-expire.today" }}</span>
{{ else if eq .ExpiresIn 1 }}
<span class="badge badge-light float-right">in 1 day</span>
<span class="badge badge-light float-right">{{ tr "session.template.form.label-expire.when" }}</span>
{{ else }}
<span class="badge badge-light float-right">in {{ .ExpiresIn }} days</span>
{{ end }}
<label class="mb-0 d-block">Browser</label>
<label class="mb-0 d-block">{{ tr "session.template.form.label-browser" }}</label>
<p class="small w-75 d-inline-block">
{{ .UserAgent }}
</p>
{{ if .SameUserAgent}}
<span class="badge badge-light float-right">This browser</span>
<span class="badge badge-light float-right">{{ tr "session.template.form.span-browser" }}</span>
{{ end }}
</div>
{{ end }}
+16 -16
View File
@@ -1,6 +1,6 @@
{{ template "inc_header.html.tpl" . }}
<div class="card-body p-0">
<h1 class="h4 card-title p-3 border-bottom">Sign up</h1>
<h1 class="h4 card-title p-3 border-bottom">{{ tr "singup.template.title" }}</h1>
<form
method="POST"
action="{{ links.Signup }}"
@@ -15,67 +15,67 @@
<div class="mb-3">
<label>
E-mail *
{{ tr "singup.template.form.email.label" }}
</label>
<input
type="email"
class="form-control"
name="email"
required
placeholder="email@domain.ltd"
placeholder="{{ tr "singup.template.form.email.placeholder" }}"
autocomplete="username"
value="{{ .form.email }}"
aria-label="Email">
aria-label="{{ tr "singup.template.form.email.aria-label" }}">
</div>
<div class="mb-3">
<label>
Password *
{{ tr "singup.template.form.password.label" }}
</label>
<input
type="password"
class="form-control"
name="password"
required
placeholder="Password"
placeholder="{{ tr "singup.template.form.password.placeholder" }}"
autocomplete="new-password"
aria-label="Password">
aria-label="{{ tr "singup.template.form.password.aria-label" }}">
</div>
<div class="mb-3">
<label>
Full Name
{{ tr "singup.template.form.name.label" }}
</label>
<input
type="text"
class="form-control"
name="name"
placeholder="Your full name"
placeholder="{{ tr "singup.template.form.name.placeholder" }}"
value="{{ .form.name }}"
autocomplete="name"
aria-label="Full name">
aria-label="{{ tr "singup.template.form.name.aria-label" }}">
</div>
<div class="mb-3">
<label>
Short name, nickname or handle
{{ tr "singup.template.form.nickname.label" }}
</label>
<input
type="text"
class="form-control handle-mask"
name="handle"
placeholder="Short name, nickname or handle"
placeholder="{{ tr "singup.template.form.nickname.placeholder" }}"
value="{{ .form.handle }}"
autocomplete="handle"
aria-label="Handle">
aria-label="{{ tr "singup.template.form.nickname.aria-label" }}">
</div>
<div>
<button
id="submit"
class="btn btn-primary btn-block btn-lg"
type="submit"
>Submit</button>
>{{ tr "singup.template.form.button.sign-up" }}</button>
</div>
</form>
<div class="text-center my-3">Already have an account?
<a href="{{ links.Login }}">Log in here</a>
<div class="text-center my-3">{{ tr "singup.template.form.link.alternative" }}
<a href="{{ links.Login }}">{{ tr "singup.template.form.link.login" }}</a>
</div>
</div>
{{ template "inc_footer.html.tpl" . }}
+6 -4
View File
@@ -1,13 +1,14 @@
package handlers
import (
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/pkg/errors"
"github.com/cortezaproject/corteza-server/system/types"
"sort"
"strconv"
"strings"
"time"
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/pkg/errors"
"github.com/cortezaproject/corteza-server/system/types"
)
type (
@@ -59,9 +60,10 @@ func (h *AuthHandlers) clientsProc(req *request.AuthReq) error {
return err
}
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Client authorization deleted",
Text: t("authorized-clients.alerts.text"),
})
}
+3 -1
View File
@@ -22,10 +22,12 @@ func (h *AuthHandlers) changePasswordProc(req *request.AuthReq) (err error) {
req.Request.PostFormValue("newPassword"),
)
t := translator(req, "auth")
if err == nil {
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Password successfully changed.",
Text: t("change-password.alerts.text"),
})
req.RedirectTo = GetLinks().Profile
+6 -2
View File
@@ -98,7 +98,9 @@ func (h *AuthHandlers) loginProc(req *request.AuthReq) (err error) {
zap.Bool("perm-login", isPerm),
zap.Duration("lifetime", lifetime),
)
req.PushAlert("You are now logged-in")
t := translator(req, "auth")
req.PushAlert(t("login.alerts.logged-in"))
if req.AuthUser.PendingEmailOTP() {
// Email OTP enforced (globally or by user sec. policy)
@@ -153,5 +155,7 @@ func (h *AuthHandlers) localDisabledAlert(req *request.AuthReq) {
req.RedirectTo = GetLinks().Login
}
req.PushDangerAlert("Local accounts disabled")
t := translator(req, "auth")
req.PushDangerAlert(t("login.alert.local-disabled"))
}
+9 -3
View File
@@ -26,7 +26,9 @@ func (h AuthHandlers) mfaForm(req *request.AuthReq) (err error) {
return nil
}
req.PushAlert("Email OTP resent")
t := translator(req, "auth")
req.PushAlert(t("mfa.handle.email-resent"))
req.RedirectTo = GetLinks().Mfa
}
@@ -55,7 +57,9 @@ func (h AuthHandlers) mfaProc(req *request.AuthReq) (err error) {
return nil
}
req.PushAlert("Email OTP valid")
t := translator(req, "auth")
req.PushAlert(t("mfa.handle.email-resent"))
req.AuthUser.CompleteEmailOTP()
case "verifyTotp":
@@ -69,7 +73,9 @@ func (h AuthHandlers) mfaProc(req *request.AuthReq) (err error) {
return nil
}
req.PushAlert("TOTP valid")
t := translator(req, "auth")
req.PushAlert(t("mfa.handle.topt-valid"))
req.AuthUser.CompleteTOTP()
}
+7 -4
View File
@@ -3,13 +3,14 @@ package handlers
import (
"encoding/base32"
"fmt"
"math/rand"
"net/url"
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/errors"
"github.com/cortezaproject/corteza-server/system/types"
"go.uber.org/zap"
"math/rand"
"net/url"
"rsc.io/qr"
)
@@ -69,10 +70,11 @@ func (h AuthHandlers) mfaTotpConfigProc(req *request.AuthReq) (err error) {
req.Request.PostFormValue("code"),
)
t := translator(req, "auth")
if err == nil {
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Two factor authentication with TOTP enabled",
Text: t("mfa_totp.alerts.text-TFA-enabled"),
})
// Make sure we update User's data in the session
@@ -172,10 +174,11 @@ func (h AuthHandlers) mfaTotpDisableProc(req *request.AuthReq) (err error) {
req.Request.PostFormValue("code"),
)
t := translator(req, "auth")
if err == nil {
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Two factor authentication with TOTP disabled",
Text: t("mfa_totp.alerts.text-TFA_disabled"),
})
// Make sure we update User's data in the session
+5 -2
View File
@@ -91,9 +91,11 @@ func (h AuthHandlers) oauth2AuthorizeClient(req *request.AuthReq) (err error) {
request.SetOauth2Client(req.Session, nil)
request.SetOauth2AuthParams(req.Session, nil)
req.RedirectTo = GetLinks().Profile
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "danger",
Text: fmt.Sprintf("cannot authorize '%s', no permissions.", req.Client),
Text: fmt.Sprintf(t("oauth2_authorize_client.alerts.no-auth-or-prems"), req.Client),
})
return nil
}
@@ -140,9 +142,10 @@ func (h AuthHandlers) oauth2AuthorizeClientProc(req *request.AuthReq) (err error
//
request.SetOauth2AuthParams(req.Session, nil)
req.RedirectTo = GetLinks().Profile
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "warning",
Text: "Access for client denied",
Text: t("oauth2_authorize_client.alerts.client-access-denied"),
})
return
}
+6 -3
View File
@@ -67,9 +67,10 @@ func (h *AuthHandlers) resetPasswordForm(req *request.AuthReq) (err error) {
h.Log.Warn("invalid password reset token used", zap.Error(err))
req.RedirectTo = GetLinks().RequestPasswordReset
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "warning",
Text: "Invalid or expired password reset token, please repeat password reset request.",
Text: t("password_reset_requested.alert.inv-exp-passw-token"),
})
}
@@ -83,9 +84,10 @@ func (h *AuthHandlers) resetPasswordProc(req *request.AuthReq) (err error) {
err = h.AuthService.SetPassword(req.Context(), req.AuthUser.User.ID, req.Request.PostFormValue("password"))
if err == nil {
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Password successfully reset.",
Text: t("password_reset_requested.alert.pass-reset-success"),
})
req.RedirectTo = GetLinks().Profile
@@ -116,8 +118,9 @@ func (h *AuthHandlers) onlyIfPasswordResetEnabled(fn handlerFn) handlerFn {
func (h *AuthHandlers) passwordResetDisabledAlert(req *request.AuthReq) {
req.RedirectTo = GetLinks().Login
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "danger",
Text: "Password reset disabled",
Text: t("password_reset_requested.alert.pass-reset-disabled"),
})
}
+4 -2
View File
@@ -40,9 +40,10 @@ func (h *AuthHandlers) profileProc(req *request.AuthReq) error {
req.AuthUser.User = user
req.AuthUser.Save(req.Session)
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Profile successfully updated.",
Text: t("profile.alerts.profile-updated"),
})
req.RedirectTo = GetLinks().Profile
@@ -63,9 +64,10 @@ func (h *AuthHandlers) profileProc(req *request.AuthReq) error {
"name": u.Name,
})
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "danger",
Text: "Could not update profile due to input errors",
Text: t("profile.alerts.profile-update-fail"),
})
h.Log.Warn("handled error", zap.Error(err))
+2 -1
View File
@@ -35,9 +35,10 @@ func (h *AuthHandlers) securityProc(req *request.AuthReq) error {
if user, err := h.AuthService.ConfigureEmailOTP(req.Context(), req.AuthUser.User.ID, enable); err != nil {
return err
} else {
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Two factor authentication with TOTP disabled",
Text: t("security.TFA-TOTP-disabled"),
})
// Make sure we update User's data in the session
+7 -4
View File
@@ -3,10 +3,11 @@ package handlers
import (
"crypto/md5"
"fmt"
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/system/types"
"sort"
"time"
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/system/types"
)
type (
@@ -74,9 +75,10 @@ func (h *AuthHandlers) sessionsProc(req *request.AuthReq) error {
}
}
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "All sessions but current deleted",
Text: t("session.alerts.delete-sessions-but-current"),
})
case len(req.Request.PostFormValue("delete")) > 0:
for _, s := range ss {
@@ -89,9 +91,10 @@ func (h *AuthHandlers) sessionsProc(req *request.AuthReq) error {
}
}
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Session deleted",
Text: t("session.alerts.session-deleted"),
})
}
+8 -4
View File
@@ -31,9 +31,10 @@ func (h *AuthHandlers) signupProc(req *request.AuthReq) error {
if err == nil {
if newUser.EmailConfirmed {
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Sign-up successful.",
Text: t("singup.alerts.singup-successful"),
})
h.Log.Info(
@@ -101,9 +102,10 @@ func (h *AuthHandlers) confirmEmail(req *request.AuthReq) (err error) {
if err == nil {
// redirect back to self (but without token and with user in session
h.Log.Debug("valid email confirmation token found, redirecting to profile")
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "primary",
Text: "Email address confirmed, you're now logged-in.",
Text: t("singup.alerts.email-confirmed-logged-in"),
})
req.RedirectTo = GetLinks().Profile
@@ -130,9 +132,10 @@ func (h *AuthHandlers) confirmEmail(req *request.AuthReq) (err error) {
req.RedirectTo = GetLinks().Profile
}
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "warning",
Text: "Invalid or expired email confirmation token, please resend confirmation request.",
Text: t("singup.alerts.inv-or-exp-token"),
})
return nil
@@ -151,8 +154,9 @@ func (h *AuthHandlers) onlyIfSignupEnabled(fn handlerFn) handlerFn {
func (h *AuthHandlers) signupDisabledAlert(req *request.AuthReq) {
req.RedirectTo = GetLinks().Login
t := translator(req, "auth")
req.NewAlerts = append(req.NewAlerts, request.Alert{
Type: "danger",
Text: "Signup disabled",
Text: t("singup.alerts.singup-disabled"),
})
}