forked from Cookies_Github_mirror/AquaDX
feature: password reset
This commit is contained in:
@@ -80,6 +80,7 @@
|
||||
<Router {url}>
|
||||
<Route path="/" component={Welcome} />
|
||||
<Route path="/verify" component={Welcome} /> <!-- For email verification only, backwards compatibility with AquaNet2 in the future -->
|
||||
<Route path="/reset-password" component={Welcome} />
|
||||
<Route path="/home" component={Home} />
|
||||
<Route path="/ranking" component={Ranking} />
|
||||
<Route path="/ranking/:game" component={Ranking} />
|
||||
|
||||
@@ -34,21 +34,29 @@ export const EN_REF_Welcome = {
|
||||
'back': 'Back',
|
||||
'email': 'Email',
|
||||
'password': 'Password',
|
||||
'new-password': 'New password',
|
||||
'username': 'Username',
|
||||
'welcome.btn-login': 'Log in',
|
||||
'welcome.btn-signup': 'Sign up',
|
||||
'welcome.btn-reset-password': 'Forgot password?',
|
||||
'welcome.btn-submit-reset-password': 'Send reset link',
|
||||
'welcome.btn-submit-new-password': 'Change password',
|
||||
'welcome.email-missing': 'Email is required',
|
||||
'welcome.password-missing': 'Password is required',
|
||||
'welcome.email-password-missing': 'Email and password are required',
|
||||
'welcome.username-missing': 'Username/email is required',
|
||||
'welcome.waiting-turnstile': 'Waiting for Turnstile to verify your network environment...',
|
||||
'welcome.turnstile-error': 'Error verifying your network environment. Please turn off your VPN and try again.',
|
||||
'welcome.turnstile-timeout': 'Network verification timed out. Please try again.',
|
||||
'welcome.verification-sent': 'A verification email has been sent to ${email}. Please check your inbox!',
|
||||
'welcome.reset-password-sent': 'A password reset email has been sent to ${email}. Please check your inbox!',
|
||||
'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.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.',
|
||||
'welcome.password-reset-done': 'Your password has been changed! You can log in now.',
|
||||
}
|
||||
|
||||
export const EN_REF_LEADERBOARD = {
|
||||
|
||||
@@ -163,12 +163,22 @@ async function login(user: { email: string, password: string, turnstile: string
|
||||
localStorage.setItem('token', data.token)
|
||||
}
|
||||
|
||||
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 }) {
|
||||
return await post('/api/v2/user/change-password', user)
|
||||
}
|
||||
|
||||
const isLoggedIn = () => !!localStorage.getItem('token')
|
||||
const ensureLoggedIn = () => !isLoggedIn() && (window.location.href = '/')
|
||||
|
||||
export const USER = {
|
||||
register,
|
||||
login,
|
||||
resetPassword,
|
||||
changePassword,
|
||||
confirmEmail: (token: string) =>
|
||||
post('/api/v2/user/confirm-email', { token }),
|
||||
me: (): Promise<AquaNetUser> => {
|
||||
|
||||
@@ -20,31 +20,33 @@
|
||||
|
||||
let error = ""
|
||||
let verifyMsg = ""
|
||||
let code = ""
|
||||
|
||||
if (USER.isLoggedIn()) {
|
||||
window.location.href = "/home"
|
||||
}
|
||||
if (location.pathname !== '/') {
|
||||
location.href = `/${params.get('code') ? `?code=${params.get('code')}` : ""}`
|
||||
} else
|
||||
if (params.get('code')) {
|
||||
|
||||
if (params.get('code')) {
|
||||
code = params.get('code')!
|
||||
if (location.pathname === '/verify') {
|
||||
state = 'verify'
|
||||
verifyMsg = t("welcome.verifying")
|
||||
submitting = true
|
||||
|
||||
// Send request to server
|
||||
USER.confirmEmail(params.get('code')!)
|
||||
USER.confirmEmail(code)
|
||||
.then(() => {
|
||||
verifyMsg = t('welcome.verified')
|
||||
submitting = false
|
||||
|
||||
// Clear the query param
|
||||
window.history.replaceState({}, document.title, window.location.pathname)
|
||||
})
|
||||
.catch(e => verifyMsg = t('welcome.verification-failed', { message: e.message }))
|
||||
// Clear the query param
|
||||
window.history.replaceState({}, document.title, window.location.pathname)
|
||||
})
|
||||
.catch(e => verifyMsg = t('welcome.verification-failed', { message: e.message }))
|
||||
}
|
||||
|
||||
else if (location.pathname === '/reset-password') {
|
||||
state = 'reset'
|
||||
}
|
||||
}
|
||||
async function submit(): Promise<any> {
|
||||
submitting = true
|
||||
|
||||
@@ -111,6 +113,52 @@ if (location.pathname !== '/') {
|
||||
submitting = false
|
||||
}
|
||||
|
||||
async function resetPassword(): Promise<any> {
|
||||
submitting = true;
|
||||
|
||||
if (email === "") {
|
||||
error = t("welcome.email-missing")
|
||||
return submitting = false
|
||||
}
|
||||
|
||||
// Send request to server
|
||||
await USER.resetPassword({ email, turnstile })
|
||||
.then(() => {
|
||||
// Show email sent message, reusing email verify page
|
||||
state = 'verify'
|
||||
verifyMsg = t("welcome.reset-password-sent", { email })
|
||||
})
|
||||
.catch(e => {
|
||||
error = e.message
|
||||
submitting = false
|
||||
turnstileReset()
|
||||
})
|
||||
|
||||
submitting = false;
|
||||
}
|
||||
|
||||
async function changePassword(): Promise<any> {
|
||||
submitting = true
|
||||
|
||||
if (password === "") {
|
||||
error = t("welcome.password-missing")
|
||||
return submitting = false
|
||||
}
|
||||
|
||||
// Send request to server
|
||||
await USER.changePassword({ code, password })
|
||||
.then(() => {
|
||||
verifyMsg = t("welcome.password-reset-done")
|
||||
})
|
||||
.catch(e => {
|
||||
error = e.message
|
||||
submitting = false
|
||||
turnstileReset()
|
||||
})
|
||||
|
||||
submitting = false
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<main id="home" class="no-margin">
|
||||
@@ -143,6 +191,9 @@ if (location.pathname !== '/') {
|
||||
{isSignup ? t('welcome.btn-signup') : t('welcome.btn-login')}
|
||||
{/if}
|
||||
</button>
|
||||
{#if !submitting}
|
||||
<button on:click={() => state = 'submitreset'}>{t('welcome.btn-reset-password')}</button>
|
||||
{/if}
|
||||
{#if TURNSTILE_SITE_KEY}
|
||||
<Turnstile siteKey={TURNSTILE_SITE_KEY} bind:reset={turnstileReset}
|
||||
on:turnstile-callback={e => console.log(turnstile = e.detail.token)}
|
||||
@@ -151,6 +202,32 @@ if (location.pathname !== '/') {
|
||||
on:turnstile-timeout={_ => console.log(error = t('welcome.turnstile-timeout'))} />
|
||||
{/if}
|
||||
</div>
|
||||
{:else if state === "submitreset"}
|
||||
<div class="login-form" transition:slide>
|
||||
{#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>
|
||||
<input type="email" placeholder={t('email')} bind:value={email}>
|
||||
<button on:click={resetPassword}>
|
||||
{#if submitting}
|
||||
<Icon icon="line-md:loading-twotone-loop"/>
|
||||
{:else}
|
||||
{t('welcome.btn-submit-reset-password')}
|
||||
{/if}
|
||||
</button>
|
||||
{#if TURNSTILE_SITE_KEY}
|
||||
<Turnstile siteKey={TURNSTILE_SITE_KEY} bind:reset={turnstileReset}
|
||||
on:turnstile-callback={e => console.log(turnstile = e.detail.token)}
|
||||
on:turnstile-error={_ => console.log(error = t("welcome.turnstile-error"))}
|
||||
on:turnstile-expired={_ => window.location.reload()}
|
||||
on:turnstile-timeout={_ => console.log(error = t('welcome.turnstile-timeout'))} />
|
||||
{/if}
|
||||
</div>
|
||||
{:else if state === "verify"}
|
||||
<div class="login-form" transition:slide>
|
||||
<span>{verifyMsg}</span>
|
||||
@@ -158,6 +235,17 @@ if (location.pathname !== '/') {
|
||||
<button on:click={() => state = 'home'} transition:slide>{t('back')}</button>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if state === "reset"}
|
||||
<div class="login-form" transition:slide>
|
||||
<input type="password" placeholder={t('new-password')} bind:value={password}>
|
||||
<button on:click={changePassword}>
|
||||
{#if submitting}
|
||||
<Icon icon="line-md:loading-twotone-loop"/>
|
||||
{:else}
|
||||
{t('welcome.btn-submit-new-password')}
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user