Skip to content

Commit

Permalink
password login & reset
Browse files Browse the repository at this point in the history
  • Loading branch information
haojiezhe12345 committed Aug 20, 2024
1 parent 529bc36 commit 28d222b
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 29 deletions.
32 changes: 28 additions & 4 deletions index.css
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,29 @@ body>* {
max-width: 20rem;
}

.popupItem input[type=text] {
.popupItem .inputHelperText .help {
float: right;
margin-left: 0.375rem;
color: black;
text-decoration: underline;
cursor: pointer;
user-select: none;
}

.popupItem .inputHelperText .help::before {
content: "?";
font-family: Arial;
display: inline-block;
font-size: 0.77em;
text-align: center;
width: 1.1em;
height: 1.1em;
border-radius: 100%;
border: 1px solid black;
}

.popupItem input[type=text],
.popupItem input[type=password] {
display: block;
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.08);
Expand All @@ -1579,12 +1601,14 @@ body>* {
max-width: 70vw;
}

.popupItem input[type=text]:hover {
.popupItem input[type=text]:hover,
.popupItem input[type=password]:hover {
background-color: rgba(0, 0, 0, 0.1);
border-color: rgba(0, 0, 0, 0.4);
}

.popupItem input[type=text]:focus {
.popupItem input[type=text]:focus,
.popupItem input[type=password]:focus {
outline: none;
background-color: rgba(0, 0, 0, 0.12);
border-color: rgba(0, 0, 0, 0.7);
Expand Down Expand Up @@ -1912,7 +1936,7 @@ p.altLoginOption,
.userHome {
width: 31.25rem;
max-width: 100%;
min-height: 16.5rem !important;
min-height: 20rem !important;
box-sizing: border-box;
padding: 1.25rem 1.5rem 2rem !important;
}
Expand Down
86 changes: 67 additions & 19 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -684,9 +684,13 @@ <h2><span class="ui zh">小情侣(?)</span><span class="ui en">Minigame</s
<h2><span class="ui zh">注册/登录</span><span class="ui en">Log in / Register</span></h2>

<div class="inputHelperText"><span class="ui zh">用户名 (昵称)</span><span class="ui en">Username (nickname)</span></div>
<input type="text" v-model="loginUsername"
<input type="text" v-model="loginUsername" style="margin-bottom: 0;"
@keypress="e => e.key == 'Enter' && loginUsername.length > 0 && searchUser()">

<div class="inputHelperText" style="margin: 0.375rem 0 1rem;">
<span class="ui zh">未注册的用户将自动注册</span><span class="ui en">Newcomers will create an account automatically</span>
</div>

<p class="altLoginOption" @click="screen = 'emailLogin'; loginUser = null">
<span class="ui zh">邮箱登录</span><span class="ui en">Email login</span>
</p>
Expand All @@ -699,24 +703,40 @@ <h2><span class="ui zh">注册/登录</span><span class="ui en">Log in / Registe
<div v-if="screen == 'emailLogin'">
<h2><span class="ui zh">邮箱登录</span><span class="ui en">Log in with email</span></h2>

<div v-if="loginUser" class="emailLoginInfo">
<img :src="convertAvatarPath(loginUser.avatar)">
<div>{{ loginUser.name }}</div>
</div>

<div v-if="loginUser" class="inputHelperText">
<span class="ui zh">该账号已绑定邮箱<br>在下方输入绑定的邮箱以登录:</span><span class="ui en">This account is linked to an email<br>Enter your email to log in:</span>
</div>
<div v-else class="inputHelperText"><span class="ui zh">邮箱</span><span class="ui en">Email</span></div>

<input type="text" v-model="loginEmail"
@keypress="e => e.key == 'Enter' && loginEmail.length > 0 && emailLogin()">
<form>
<template v-if="loginUser">
<div class="emailLoginInfo">
<img :src="convertAvatarPath(loginUser.avatar)">
<div>{{ loginUser.name }}</div>
</div>
<div v-if="loginUser.hasEmail" class="inputHelperText">
<span class="ui zh">该账号已绑定邮箱<br>在下方输入绑定的邮箱以登录:</span><span class="ui en">This account is linked to an email<br>Enter your email to log in:</span>
</div>
</template>
<div v-else class="inputHelperText"><span class="ui zh">邮箱</span><span class="ui en">Email</span></div>

<input v-if="loginUser ? loginUser.hasEmail : true" type="text" v-model="loginEmail" autocomplete="email">

<template v-if="loginUser ? loginUser.hasPassword : true">
<div class="inputHelperText">
<template v-if="loginUser">
<span class="ui zh">密码</span><span class="ui en">Password</span>
</template>
<template v-else>
<span class="ui zh">密码 (没有可不填)</span><span class="ui en">Password (omit if not set)</span>
</template>
<span class="help" @click="gotoForgotPassword"><span class="ui zh">忘记密码</span><span class="ui en">Forgot password</span></span>
</div>
<input type="password" v-model="loginPassword" autocomplete="current-password"
@keypress="e => e.key == 'Enter' && (loginEmail.length > 0 || loginPassword.length > 0) && emailLogin()">
</template>
</form>

<p v-if="!loginUser" class="altLoginOption" @click="screen = 'usernameLogin'">
<span class="ui zh">用户名登录</span><span class="ui en">Username login</span>
</p>

<button class="okBtn" :disabled="loginEmail.length == 0" @click="emailLogin()">
<button class="okBtn" :disabled="loginEmail.length == 0 && loginPassword.length == 0" @click="emailLogin()">
<span class="ui zh">下一步 →</span><span class="ui en">Continue →</span>
</button>

Expand Down Expand Up @@ -766,17 +786,24 @@ <h2><span class="ui zh">注册账号</span><span class="ui en">Registration</spa
<input type="checkbox" id="hideTopComment" v-model="regUseEmail" :disabled="regRequireEmail">
</label>

<div v-if="regUseEmail">
<form v-if="regUseEmail">
<div v-if="regRequireEmail" class="inputHelperText">
<span class="ui zh">该昵称已被使用<br>要使用重复的昵称,必须绑定邮箱</span>
<span class="ui en">This nickname is already taken<br>To use a same name, you must provide an email</span>
</div>
<div v-else class="inputHelperText"><span class="ui zh">邮箱</span><span class="ui en">Enter your email</span></div>
<input type="text" v-model="regEmail">
<div class="inputHelperText"><span class="ui zh">暂不支持找回邮箱、设置密码</span><span class="ui en">Email recovery and password setting are not supported at this moment.</span></div>
</div>
<input type="text" v-model="regEmail" autocomplete="email">

<div class="inputHelperText"><span class="ui zh">密码 (选填)</span><span class="ui en">Password (optional)</span></div>
<input type="password" v-model="regPassword" autocomplete="current-password">

<button class="okBtn" :disabled="regName.length == 0 || (regUseEmail && regEmail.length == 0)" @click="register()">
<template v-if="regPassword.length > 0">
<div class="inputHelperText"><span class="ui zh">确认密码</span><span class="ui en">Confirm password</span></div>
<input type="password" v-model="regPasswordConfirm">
</template>
</form>

<button class="okBtn" :disabled="regName.length == 0 || (regUseEmail && (regEmail.length == 0 || (regPassword.length > 0 && regPassword != regPasswordConfirm)))" @click="register()">
<span class="ui zh">注册 →</span><span class="ui en">Register →</span>
</button>

Expand All @@ -794,6 +821,26 @@ <h2 v-html="title"></h2>
</div>
</template>

<template id="setPasswordPopup">
<div>
<h2><span class="ui zh">设置新密码</span><span class="ui en">Set new password</span></h2>

<div v-if="!userHasEmail" class="inputHelperText" style="color: red; font-weight: bold;">
<span class="ui zh">该账号未绑定邮箱, 设置密码后, 一旦忘记密码将无法找回<br>建议先绑定邮箱再设置密码</span>
<span class="ui en">This account doesn't have an email, which means you won't be able to reset password if you forget it.<br>It's strongly recommended to link an email before you proceed.</span>
<br><br>
</div>

<div class="inputHelperText"><span class="ui zh">新密码</span><span class="ui en">Enter new password</span></div>
<input type="text" v-model="password" autocomplete="new-password">

<div class="inputHelperText"><span class="ui zh">确认密码</span><span class="ui en">Confirm password</span></div>
<input type="text" v-model="passwordConfirm">

<button class="okBtn" :disabled="password && password != passwordConfirm" @click="submit()"><span class="ui zh">确定 ✔</span><span class="ui en">OK ✔</span></button>
</div>
</template>

<template id="setAvatarPopup">
<div class="setAvatarPopup">
<h2><span class="ui zh">设置头像</span><span class="ui en">Set avatar</span></h2>
Expand Down Expand Up @@ -826,6 +873,7 @@ <h2><span class="ui zh">设置头像</span><span class="ui en">Set avatar</span>
<li onclick="User.changeName()"><span class="ui zh">修改昵称</span><span class="ui en">Change nickname</span></li>
<li onclick="User.changeAvatar()"><span class="ui zh">修改头像</span><span class="ui en">Change avatar</span></li>
<li onclick="User.changeEmail()"><span class="ui zh">修改邮箱</span><span class="ui en">Change email</span></li>
<li onclick="User.changePassword()"><span class="ui zh">修改密码</span><span class="ui en">Change password</span></li>
</ul>
</div>
<div onclick="User.logout()"><img src="https://haojiezhe12345.top:82/madohomu/res/logout.svg"><span class="ui zh">退出登录</span><span class="ui en">Log out</span></div>
Expand Down
107 changes: 101 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,8 @@ const User = {
FloatMsgs.show({
type: 'info', persist: true,
msg: /*html*/`
<span class="ui zh">账号系统已升级, 您现在可以设置邮箱了</span>
<span class="ui en">Account system has been upgraded, you can bind an email now.</span>
<span class="ui zh">账号系统已升级, 您现在可以设置邮箱/密码了</span>
<span class="ui en">Account system has been upgraded, you can set email/password now.</span>
`})
}
})
Expand All @@ -761,12 +761,15 @@ const User = {

loginUsername: '',
loginEmail: '',
loginPassword: '',

userFindResult: [],
loginUser: null,

regName: '',
regEmail: '',
regPassword: '',
regPasswordConfirm: '',
regUseEmail: false,
regRequireEmail: false,
}),
Expand Down Expand Up @@ -809,7 +812,8 @@ const User = {
XHR.post('user/register', {
avatar: this.$refs.avatarPreview.src.split(';base64,')[1],
name: this.regName,
email: this.regUseEmail ? this.regEmail || undefined : undefined
email: this.regUseEmail ? this.regEmail || undefined : undefined,
password: this.regUseEmail ? this.regPassword || undefined : undefined,
}).then(r => {
if (r.code == 1) {
XHR.token = r.data
Expand All @@ -823,15 +827,21 @@ const User = {

userFindLogin(index) {
this.loginUser = this.userFindResult.length == 1 ? this.userFindResult[0] : this.userFindResult[index]
if (this.loginUser.hasEmail) {
if (this.loginUser.hasEmail || this.loginUser.hasPassword) {
this.screen = 'emailLogin'
this.loginEmail = ''
this.loginPassword = ''
} else {
this.login({ name: this.loginUser.name })
}
},

emailLogin() {
this.login({ email: this.loginEmail })
this.login({
name: this.loginUser && !this.loginUser.hasEmail ? this.loginUser.name : undefined,
email: this.loginEmail || undefined,
password: this.loginPassword || undefined,
})
},

login(payload) {
Expand All @@ -845,6 +855,41 @@ const User = {
}
})
},

gotoForgotPassword() {
if (this.loginUser && !this.loginUser.hasEmail) {
FloatMsgs.show({
type: 'warn', persist: true, msg: /*html*/`
<span class="ui zh">该账号未绑定邮箱, 无法重置密码<br>请联系站长: 3112611479@qq.com</span>
<span class="ui en">This account doesn't have an email, for password resets, you must contact: 3112611479@qq.com</span>`
})
return
}
Popup.show("promptInputPopup", {
title: '<span class="ui zh">忘记密码</span><span class="ui en">Forgot password</span>',
subtitle: /*html*/`
<span class="ui zh">输入你想要找回密码的邮箱<br>我们将发送一份重置密码的邮件, 然后您可以设置新密码</span>
<span class="ui en">Enter the email you wish to recover password.<br>We will then send you a password reset link via email.</span>
`,
text: this.loginEmail,
action(email) {
this.disabled = true
XHR.post('user/resetpassword' + obj2queryString({ email })).then(r => {
if (r.code == 1) {
this.$emit('close')
FloatMsgs.show({
type: 'success', persist: true, msg: /*html*/`
<span class="ui zh">密码重置邮件已发送! 请检查收件箱</span>
<span class="ui en">A password reset link was sent to your email, check your inbox</span>`
})
}
this.disabled = false
}).catch(() => {
this.disabled = false
})
}
})
},
},
})

Expand Down Expand Up @@ -877,6 +922,48 @@ const User = {
},
})

Vue.component('setPasswordPopup', {
template: '#setPasswordPopup',

props: ['passwordResetToken'],

data: () => ({
password: '',
passwordConfirm: '',
userHasEmail: true,
}),

methods: {
submit() {
if (this.passwordResetToken) {
XHR.post('action', {
id: this.passwordResetToken,
data: this.password
}).then(r => {
if (r.code == 1) {
this.$emit('close')
FloatMsgs.show({ type: 'success', msg: '<span class="ui zh">密码重置成功! 请重新登录</span><span class="ui en">Password reset successfully! Try log in again</span>' })
location.hash = ''
}
})
} else {
XHR.put('user/update', { password: this.password }).then(r => {
if (r.code == 1) {
this.$emit('close')
FloatMsgs.show({ type: 'success', msg: '<span class="ui zh">密码修改成功</span><span class="ui en">Password updated successfully</span>' })
}
})
}
},
},

mounted() {
if (!this.passwordResetToken) {
User.getMe().then(r => this.userHasEmail = r.hasEmail)
}
},
})

Vue.component('userHome', {
template: '#userHome',

Expand Down Expand Up @@ -1006,7 +1093,6 @@ const User = {
<span class="ui zh">邮件发送成功! 请打开邮件中的链接, 以确认修改</span>
<span class="ui en">Confirmation email sent, please check your inbox</span>`
})
loadUserInfo()
}
this.disabled = false
}).catch(() => {
Expand All @@ -1017,6 +1103,10 @@ const User = {
))
},

changePassword() {
Popup.show('setPasswordPopup')
},

changeAvatar() {
Popup.show('setAvatarPopup')
},
Expand Down Expand Up @@ -2748,6 +2838,11 @@ if (location.hash.startsWith('#confirmemail=')) {
})
}

if (location.hash.startsWith('#resetpassword=')) {
let passwordResetToken = location.hash.replace('#resetpassword=', '')
Popup.show('setPasswordPopup', { passwordResetToken })
}

window.onhashchange = function (e) {
//console.log(e.oldURL.split('#')[1], e.newURL.split('#')[1])
if (e.oldURL.split('#')[1] == 'view-img') {
Expand Down

0 comments on commit 28d222b

Please sign in to comment.