mirror of
https://github.com/MewoLab/AquaDX.git
synced 2025-10-25 12:02:40 +00:00
fix: bug fixes to password reset (INCOMPLETE)
This commit is contained in:
parent
39ed8af840
commit
c01c40fe45
@ -53,6 +53,8 @@ export const EN_REF_Welcome = {
|
||||
'welcome.verify-state-0': 'You haven\'t verified your email. A verification email had been sent to your inbox less than a minute ago. Please check your inbox!',
|
||||
'welcome.verify-state-1': 'You haven\'t verified your email. We\'ve already sent 3 emails over the last 24 hours so we\'ll not send another one. Please check your inbox!',
|
||||
'welcome.verify-state-2': 'You haven\'t verified your email. We just sent you another verification email. Please check your inbox!',
|
||||
'welcome.reset-state-0': 'A reset email had been sent to your inbox less than a minute ago. Please check your inbox!',
|
||||
'welcome.reset-state-1': 'We\'ve already sent 3 emails over the last 24 hours so we\'ll not send another one. Please check your inbox!',
|
||||
'welcome.verifying': 'Verifying your email... please wait.',
|
||||
'welcome.verified': 'Your email has been verified! You can now log in now.',
|
||||
'welcome.verification-failed': 'Verification failed: ${message}. Please try again.',
|
||||
|
||||
@ -167,7 +167,7 @@ async function resetPassword(user: { email: string, turnstile: string }) {
|
||||
return await post('api/v2/user/reset-password', user)
|
||||
}
|
||||
|
||||
async function changePassword(user: { code: string, password: string }) {
|
||||
async function changePassword(user: { token: string, password: string }) {
|
||||
return await post('/api/v2/user/change-password', user)
|
||||
}
|
||||
|
||||
|
||||
@ -20,20 +20,20 @@
|
||||
|
||||
let error = ""
|
||||
let verifyMsg = ""
|
||||
let code = ""
|
||||
let token = ""
|
||||
|
||||
if (USER.isLoggedIn()) {
|
||||
window.location.href = "/home"
|
||||
}
|
||||
if (params.get('code')) {
|
||||
code = params.get('code')!
|
||||
token = params.get('code')!
|
||||
if (location.pathname === '/verify') {
|
||||
state = 'verify'
|
||||
verifyMsg = t("welcome.verifying")
|
||||
submitting = true
|
||||
|
||||
// Send request to server
|
||||
USER.confirmEmail(code)
|
||||
USER.confirmEmail(token)
|
||||
.then(() => {
|
||||
verifyMsg = t('welcome.verified')
|
||||
submitting = false
|
||||
@ -104,7 +104,7 @@
|
||||
}
|
||||
else {
|
||||
error = e.message
|
||||
submitting = false
|
||||
submitting = false // unnecessary? see line 113, same for both reset functions
|
||||
turnstileReset()
|
||||
}
|
||||
})
|
||||
@ -121,6 +121,12 @@
|
||||
return submitting = false
|
||||
}
|
||||
|
||||
if (TURNSTILE_SITE_KEY && turnstile === "") {
|
||||
// Sleep for 100ms to allow Turnstile to finish
|
||||
error = t("welcome.waiting-turnstile")
|
||||
return setTimeout(resetPassword, 100)
|
||||
}
|
||||
|
||||
// Send request to server
|
||||
await USER.resetPassword({ email, turnstile })
|
||||
.then(() => {
|
||||
@ -129,12 +135,22 @@
|
||||
verifyMsg = t("welcome.reset-password-sent", { email })
|
||||
})
|
||||
.catch(e => {
|
||||
error = e.message
|
||||
submitting = false
|
||||
turnstileReset()
|
||||
if (e.message === "Reset request rejected - STATE_0") {
|
||||
state = 'verify'
|
||||
verifyMsg = t("welcome.reset-state-0")
|
||||
}
|
||||
else if (e.message === "Reset request rejected - STATE_1") {
|
||||
state = 'verify'
|
||||
verifyMsg = t("welcome.reset-state-1")
|
||||
}
|
||||
else {
|
||||
error = e.message
|
||||
submitting = false
|
||||
turnstileReset()
|
||||
}
|
||||
})
|
||||
|
||||
submitting = false;
|
||||
submitting = false
|
||||
}
|
||||
|
||||
async function changePassword(): Promise<any> {
|
||||
@ -145,9 +161,10 @@
|
||||
return submitting = false
|
||||
}
|
||||
|
||||
// Send request to server
|
||||
await USER.changePassword({ code, password })
|
||||
// Send request to server
|
||||
await USER.changePassword({ token, password })
|
||||
.then(() => {
|
||||
state = 'verify'
|
||||
verifyMsg = t("welcome.password-reset-done")
|
||||
})
|
||||
.catch(e => {
|
||||
@ -174,11 +191,13 @@
|
||||
{#if error}
|
||||
<span class="error">{error}</span>
|
||||
{/if}
|
||||
<div on:click={() => state = 'home'} on:keypress={() => state = 'home'}
|
||||
role="button" tabindex="0" class="clickable">
|
||||
<Icon icon="line-md:chevron-small-left" />
|
||||
<span>{t('back')}</span>
|
||||
</div>
|
||||
{#if error != t("welcome.waiting-turnstile")}
|
||||
<div on:click={() => state = 'home'} on:keypress={() => state = 'home'}
|
||||
role="button" tabindex="0" class="clickable">
|
||||
<Icon icon="line-md:chevron-small-left" />
|
||||
<span>{t('back')}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if isSignup}
|
||||
<input type="text" placeholder={t('username')} bind:value={username}>
|
||||
{/if}
|
||||
@ -191,7 +210,7 @@
|
||||
{isSignup ? t('welcome.btn-signup') : t('welcome.btn-login')}
|
||||
{/if}
|
||||
</button>
|
||||
{#if !submitting}
|
||||
{#if state === "login" && !submitting}
|
||||
<button on:click={() => state = 'submitreset'}>{t('welcome.btn-reset-password')}</button>
|
||||
{/if}
|
||||
{#if TURNSTILE_SITE_KEY}
|
||||
@ -207,11 +226,13 @@
|
||||
{#if error}
|
||||
<span class="error">{error}</span>
|
||||
{/if}
|
||||
<div on:click={() => state = 'home'} on:keypress={() => state = 'home'}
|
||||
role="button" tabindex="0" class="clickable">
|
||||
<Icon icon="line-md:chevron-small-left" />
|
||||
<span>{t('back')}</span>
|
||||
</div>
|
||||
{#if error != t("welcome.waiting-turnstile")}
|
||||
<div on:click={() => state = 'login'} on:keypress={() => state = 'login'}
|
||||
role="button" tabindex="0" class="clickable">
|
||||
<Icon icon="line-md:chevron-small-left" />
|
||||
<span>{t('back')}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<input type="email" placeholder={t('email')} bind:value={email}>
|
||||
<button on:click={resetPassword}>
|
||||
{#if submitting}
|
||||
@ -236,7 +257,10 @@
|
||||
{/if}
|
||||
</div>
|
||||
{:else if state === "reset"}
|
||||
<div class="login-form" transition:slide>
|
||||
{#if error}
|
||||
<span class="error">{error}</span>
|
||||
{/if}
|
||||
<div class="login-form" transition:slide>
|
||||
<input type="password" placeholder={t('new-password')} bind:value={password}>
|
||||
<button on:click={changePassword}>
|
||||
{#if submitting}
|
||||
|
||||
@ -59,7 +59,7 @@ Located at: [icu.samnyan.aqua.net.UserRegistrar](icu/samnyan/aqua/net/UserRegist
|
||||
* token: String
|
||||
* **Returns**: User information
|
||||
|
||||
**/user/login** : Login with email/username and password. This will also check if the email is verified and send another confirmation
|
||||
**/user/login** : Login with email/username and password. This will also check if the email is verified and send another confirmation.
|
||||
|
||||
* email: String
|
||||
* password: String
|
||||
@ -74,6 +74,18 @@ Located at: [icu.samnyan.aqua.net.UserRegistrar](icu/samnyan/aqua/net/UserRegist
|
||||
* turnstile: String
|
||||
* **Returns**: Success message
|
||||
|
||||
**/user/reset-password** : Send the user a reset password email. This will also check if the email is verified or if many requests were sent recently.
|
||||
|
||||
* email: String
|
||||
* turnstile: String
|
||||
* **Returns** Success message
|
||||
|
||||
**/user/change-password** : Reset a user's password with a token sent through email to the user.
|
||||
|
||||
* token: String
|
||||
* password: String
|
||||
* **Returns** Success message
|
||||
|
||||
**/user/setting** : Validate and set a user setting field.
|
||||
|
||||
* token: String
|
||||
|
||||
@ -147,7 +147,7 @@ class UserRegistrar(
|
||||
}
|
||||
|
||||
@API("/reset-password")
|
||||
@Doc("Reset password with a token sent through email to the user, if it exists.", "Success message") // wtf is the second param in this annotation?
|
||||
@Doc("Reset password with a token sent through email to the user, if it exists.", "Success message")
|
||||
suspend fun resetPassword(
|
||||
@RP email: Str, @RP turnstile: Str,
|
||||
request: HttpServletRequest
|
||||
@ -163,16 +163,28 @@ class UserRegistrar(
|
||||
?: return SUCCESS // obviously dont tell them if the email exists or not
|
||||
|
||||
// Check if email is verified
|
||||
if (!user.emailConfirmed && emailProps.enable) 400 - "Email not verified" // maybe similar logic to login here
|
||||
if (!user.emailConfirmed && emailProps.enable) 400 - "Email not verified"
|
||||
|
||||
val resets = async { resetPasswordRepo.findByAquaNetUserAuId(user.auId) }
|
||||
val lasReset = resets.maxByOrNull { it.createdAt }
|
||||
|
||||
if (lastReset?.createdAt?.plusSeconds(60)?.isAfter(Instant.now()) == true) {
|
||||
400 - "Reset request rejected - STATE_0"
|
||||
}
|
||||
|
||||
// Check if we have sent more than 3 confirmation emails in the last 24 hours
|
||||
if (confirmations.count { it.createdAt.plusSeconds(60 * 60 * 24).isAfter(Instant.now()) } > 3) {
|
||||
400 - "Reset request rejected- STATE_1"
|
||||
}
|
||||
|
||||
// Send a password reset email
|
||||
emailService.sendPasswordReset(user)
|
||||
|
||||
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
@API("/change-password")
|
||||
@Doc("Change a user's password given a reset code", "Success message") // again have no idea what it is
|
||||
@Doc("Change a user's password given a reset code", "Success message")
|
||||
suspend fun changePassword(
|
||||
@RP token: Str, @RP password: Str,
|
||||
request: HttpServletRequest
|
||||
@ -188,7 +200,7 @@ class UserRegistrar(
|
||||
if (reset.createdAt.plusSeconds(60 * 60 * 24).isBefore(Instant.now())) 400 - "Token expired"
|
||||
|
||||
// Change the password
|
||||
async { userRepo.save(reset.aquaNetUser.apply { pwHash = validator.checkPwHash(password) }) } // how...
|
||||
async { userRepo.save(reset.aquaNetUser.apply { pwHash = validator.checkPwHash(password) }) }
|
||||
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
@ -84,6 +84,9 @@ class EmailService(
|
||||
.buildEmail()).thenRun { log.info("Verification email sent to ${user.email}") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reset password email to the user
|
||||
*/
|
||||
fun sendPasswordReset (user: AquaNetUser) {
|
||||
if (!props.enable) return
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
CREATE TABLE aqua_net_email_password_reset
|
||||
(
|
||||
id BIGINT AUTO_INCREMENT NOT NULL,
|
||||
token VARCHAR(255) NOT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
au_id BIGINT NULL,
|
||||
CONSTRAINT pk_email_password_reset PRIMARY KEY (id)
|
||||
);
|
||||
@ -202,7 +202,7 @@
|
||||
<table border="0" cellpadding="0" cellspacing="0" class="heading_block block-1" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad" style="padding-bottom:12px;text-align:center;width:100%;">
|
||||
<h1 style="margin: 0; color: #292929; direction: ltr; font-family: 'Montserrat', 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif; font-size: 32px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 0; margin-bottom: 0; mso-line-height-alt: 38.4px;"><span class="tinyMce-placeholder">Verify your email!</span></h1>
|
||||
<h1 style="margin: 0; color: #292929; direction: ltr; font-family: 'Montserrat', 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif; font-size: 32px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 0; margin-bottom: 0; mso-line-height-alt: 38.4px;"><span class="tinyMce-placeholder">Reset your password!</span></h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -225,7 +225,7 @@
|
||||
<w:anchorlock/>
|
||||
<v:textbox inset="0px,0px,0px,0px">
|
||||
<center style="color:#ffffff; font-family:'Trebuchet MS', Tahoma, sans-serif; font-size:16px">
|
||||
<![endif]--><a href="{{url}}" style="text-decoration:none;display:inline-block;color:#ffffff;background-color:#646cff;border-radius:8px;width:auto;border-top:0px solid transparent;font-weight:400;border-right:0px solid transparent;border-bottom:0px solid transparent;border-left:0px solid transparent;padding-top:8px;padding-bottom:8px;font-family:'Montserrat', 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;font-size:16px;text-align:center;mso-border-alt:none;word-break:keep-all;" target="_blank"><span style="padding-left:16px;padding-right:16px;font-size:16px;display:inline-block;letter-spacing:normal;"><span style="word-break: break-word; line-height: 32px;">Verify email</span></span></a><!--[if mso]></center></v:textbox></v:roundrect><![endif]--></div>
|
||||
<![endif]--><a href="{{url}}" style="text-decoration:none;display:inline-block;color:#ffffff;background-color:#646cff;border-radius:8px;width:auto;border-top:0px solid transparent;font-weight:400;border-right:0px solid transparent;border-bottom:0px solid transparent;border-left:0px solid transparent;padding-top:8px;padding-bottom:8px;font-family:'Montserrat', 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;font-size:16px;text-align:center;mso-border-alt:none;word-break:keep-all;" target="_blank"><span style="padding-left:16px;padding-right:16px;font-size:16px;display:inline-block;letter-spacing:normal;"><span style="word-break: break-word; line-height: 32px;">Reset password</span></span></a><!--[if mso]></center></v:textbox></v:roundrect><![endif]--></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user