remember me checkbox, slightly more useful email hint

This commit is contained in:
Evert Prants 2022-08-18 12:34:05 +03:00
parent 545a71e57d
commit 9cebc2ca68
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
6 changed files with 44 additions and 12 deletions

View File

@ -32,3 +32,7 @@ input.form-control {
border: 1px solid var(--form-border-hover);
}
}
.form-checkbox {
margin-top: 0.75rem;
}

View File

@ -50,10 +50,12 @@ export class LoginController {
public async loginRequest(
@Req() req: Request,
@Res() res: Response,
@Body() body: { username: string; password: string },
@Body() body: { username: string; password: string; remember: boolean },
@Query('redirectTo') redirectTo?: string,
) {
const { username, password } = this.formUtil.trimmed(body, ['username']);
const { username, password, remember } = this.formUtil.trimmed(body, [
'username',
]);
const user = await this.userService.getByUsername(username);
// User exists and password matches
@ -73,7 +75,7 @@ export class LoginController {
}
if (await this.totpService.userHasTOTP(user)) {
const challenge = { type: 'verify', user: user.uuid };
const challenge = { type: 'verify', user: user.uuid, remember };
req.session.challenge = await this.token.encryptChallenge(challenge);
res.redirect(
'/login/verify' + (redirectTo ? '?redirectTo=' + redirectTo : ''),
@ -81,6 +83,13 @@ export class LoginController {
return;
}
// Extend session cookie to a month
if (remember) {
const month = 30 * 24 * 60 * 60 * 1000;
req.session.cookie.maxAge = month;
req.session.cookie.expires = new Date(Date.now() + month);
}
req.session.user = user.uuid;
res.redirect(redirectTo ? decodeURIComponent(redirectTo) : '/');
}
@ -114,6 +123,7 @@ export class LoginController {
@Query('redirectTo') redirectTo?: string,
) {
let user: User;
let remember = false;
try {
if (!session.challenge) {
@ -129,6 +139,8 @@ export class LoginController {
if (!user) {
throw new Error('Bad challenge');
}
remember = challenge.remember;
} catch (e: any) {
req.flash('message', {
error: true,
@ -154,6 +166,12 @@ export class LoginController {
return;
}
// Extend session cookie to a month
if (remember) {
const month = 30 * 24 * 60 * 60 * 1000;
req.session.cookie.maxAge = month;
}
session.challenge = null;
session.user = user.uuid;
res.redirect(redirectTo ? decodeURIComponent(redirectTo) : '/');

View File

@ -172,7 +172,10 @@ export class SettingsController {
@Render('settings/security')
public async security(@Req() req: Request) {
const mailSplit = req.user.email.split('@');
const emailHint = `${mailSplit[0].substring(0, 1)}***@${mailSplit[1]}`;
const asterisks = ''.padStart(mailSplit[0].substring(1).length, '*');
const emailHint = `${mailSplit[0].substring(0, 1)}${asterisks}@${
mailSplit[1]
}`;
const twofactor = await this._totp.userHasTOTP(req.user);
return this._form.populateTemplate(req, {
user: req.user,

View File

@ -23,11 +23,18 @@ block body
input.form-control#username(type="text", name="username", placeholder="Username", autofocus, value=form.username)
label.form-label(for="password") Password
input.form-control#password(type="password", name="password", placeholder="Password")
div.form-checkbox
input.form-control#remember(type="checkbox", name="remember", checked=form.remember)
label(for="remember") Remember me
button.btn.btn-primary(type="submit") Log in
div.btn-group.align-self-end
a.btn.btn-link(type="button" href="/register" + (query ? ('?' + query) : '')) Create a new account
|•
a.btn.btn-link(type="button" href="/login/password") Forgot password?
div.center-box-addon
p Icy Network is a Single-Sign-On service used by other applications.
p The website may use temporary cookies for storing your login session.
p
b Icy Network is a Single-Sign-On service used by other applications.
p The website may use temporary cookies for storing your login session and ensuring your security.
| This web service is 
a(href="https://gitlab.icynet.eu/IcyNetwork/icynet-auth-server", target="_blank") completely open source
| and can be audited by anyone.

View File

@ -36,13 +36,13 @@ block settings
form(method="post", action="/account/avatar/delete")
input(type="hidden", name="_csrf", value=csrf)
button.btn.btn-link#remove-avatar(type="submit") Remove avatar
form(method="post", data-noscript, action="/account/avatar", enctype="multipart/form-data")
div.form-container
input(type="hidden", name="_csrf", value=csrf)
label.form-label(for="image") Image
input.form-control#image(type="file", name="file")
small.form-hint Must be less than 10 MB and 1:1 aspect ratio. Enable JavaScript to custom crop your image.
small.form-hint Must be less than 10 MB and 1:1 aspect ratio (square). Enable JavaScript to custom crop your image.
button.btn.btn-primary(type="submit") Change
.modal#avatar-modal(data-modal="avatar", style="display: none")
.modal__content

View File

@ -17,7 +17,7 @@ block settings
h2 Change Password
form(method="post", action="/account/security/password", autocomplete="off")
div.form-container
input#csrfa(type="hidden", name="_csrf", value=csrf)
input#csrf(type="hidden", name="_csrf", value=csrf)
label.form-label(for="password") Current Password
input.form-control#password(type="password", name="password")
label.form-label(for="new_password") New Password
@ -29,7 +29,7 @@ block settings
h2 Change Email Address
form(method="post", action="/account/security/email", autocomplete="off")
div.form-container
input#csrfb(type="hidden", name="_csrf", value=csrf)
input(type="hidden", name="_csrf", value=csrf)
label.form-label(for="current_email") Current Email Address
input.form-control#current_email(type="email", name="current_email")
small.form-hint Hint: #{emailHint}
@ -42,9 +42,9 @@ block settings
p Two-factor authentication is enabled.
a.btn.btn-primary(href="/account/two-factor/disable") Disable
else
p You can enable two-factor authentication using an authenticator app of your choice, such as
p You can enable two-factor authentication using an authenticator app of your choice, such as
b Google Authenticator
| or
| or
b andOTP
|.
a.btn.btn-primary(href="/account/two-factor/activate") Activate