增加重置密码页面和逻辑

dependabot/npm_and_yarn/fir_admin/dns-packet-1.3.4
youngS 4 years ago
parent 50d877f2f3
commit 76bde18c5a
  1. 2
      fir_client/src/components/FirBase.vue
  2. 3
      fir_client/src/components/FirLogin.vue
  3. 235
      fir_client/src/components/FirResetPwd.vue
  4. 2
      fir_client/src/components/apps/FirAppInfossecurity.vue
  5. 4
      fir_client/src/components/base/BindDomain.vue
  6. 6
      fir_client/src/router/index.js
  7. 19
      fir_ser/api/utils/baseutils.py
  8. 5
      fir_ser/api/views/apps.py
  9. 4
      fir_ser/api/views/download.py
  10. 28
      fir_ser/api/views/login.py

@ -75,7 +75,7 @@
let canvas = this.$refs.canvas; let canvas = this.$refs.canvas;
show_beautpic(this, canvas, 200); show_beautpic(this, canvas, 200);
}, watch: { }, watch: {
'$store.state.userinfo.domain_name': function () { '$store.state.userinfo': function () {
if (this.$store.state.userinfo.domain_name) { if (this.$store.state.userinfo.domain_name) {
this.$store.dispatch("dodomainshow", false); this.$store.dispatch("dodomainshow", false);
} else { } else {

@ -68,6 +68,9 @@
<el-form-item v-if="register_enable"> <el-form-item v-if="register_enable">
<el-button type="primary" @click="onRegister" plain>注册</el-button> <el-button type="primary" @click="onRegister" plain>注册</el-button>
</el-form-item> </el-form-item>
<el-form-item>
<el-link :underline="false" @click="$router.push({name: 'FirResetPwd'})" plain>忘记密码</el-link>
</el-form-item>
</el-form> </el-form>

@ -0,0 +1,235 @@
<template>
<el-container>
<div style="margin: 10px 0 10px 0 ;position:absolute;right:20px;top:auto;">
<el-button round icon="el-icon-arrow-left" @click="$router.go(-1)"/>
<el-button round icon="el-icon-s-home" @click="$router.push({name:'FirIndex'})"/>
</div>
<el-header>
<div>
<span>忘记密码</span>
</div>
</el-header>
<el-main>
<el-form ref="form" :model="form">
<el-form-item>
<el-input v-model="form.email" prefix-icon="el-icon-user" placeholder="邮箱" autofocus
clearable/>
</el-form-item>
<el-form-item style="height: 40px" v-if="cptch.cptch_image">
<el-row style="height: 40px">
<el-col :span="16">
<el-input placeholder="请输入验证码" v-model="form.authcode" maxlength="6"
@keyup.enter.native="onSubmit" clearable/>
</el-col>
<el-col :span="8">
<el-image
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 40px"
:src="cptch.cptch_image"
fit="contain" @click="get_auth_code">
</el-image>
</el-col>
</el-row>
</el-form-item>
<el-form-item>
<div id="captcha" ref="captcha"></div>
</el-form-item>
<el-form-item style="margin-top: 30px">
<el-button type="danger" :disabled="login_disable" @click="onSubmit">发送重置密码邮件</el-button>
</el-form-item>
<el-form-item style="margin-top: 30px">
<el-button type="primary" @click="onLogin">我是老用户,要登录</el-button>
</el-form-item>
<el-form-item v-if="register_enable" style="margin-top: 30px">
<el-button type="primary" @click="onRegister" plain>注册</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</template>
<script>
import {loginFun} from "@/restful";
import {checkEmail, geetest} from "@/utils";
export default {
name: "FirResetPwd",
data() {
return {
form: {
email: '',
password: '',
authcode: ''
},
cptch: {"cptch_image": '', "cptch_key": '', "length": 8},
activeName: 'username',
allow_ways: {},
rutitle: '',
rctitle: '',
register_enable: false,
login_disable: false,
}
},
methods: {
is_cptch() {
let cptch_flag = this.form.authcode.length === this.cptch.length;
if (this.cptch.cptch_key === '' || !this.cptch.cptch_key) {
cptch_flag = true
}
return cptch_flag
},
onSubmit() {
let email = this.form.email;
let authcode = this.form.authcode;
let cptch_flag = this.form.authcode.length === this.cptch.length;
if (this.cptch.cptch_key === '' || !this.cptch.cptch_key) {
cptch_flag = true
}
if (cptch_flag) {
let checke = checkEmail(this.form.email);
if (!checke) {
this.$message({
message: '邮箱输入有误',
type: 'error'
});
return
}
let params = {
"username": email,
"authcode": authcode,
"cptch_key": this.cptch.cptch_key,
"login_type": 'reset',
};
this.login_disable = true;
if (this.cptch.geetest) {
geetest(this, params, (n_params) => {
this.do_login(n_params);
})
} else {
this.do_login(params)
}
} else {
this.$message({
message: '验证码有误',
type: 'warning'
});
}
},
do_login(params) {
loginFun(data => {
if (data.code === 1000) {
this.$message({
message: '密码重置成功,请登录邮箱查看邮件',
type: 'success'
});
} else {
this.$message({
message: data.msg,
type: 'error'
});
this.get_auth_code();
}
this.login_disable = false;
}, {
"methods": "POST",
"data": params
});
},
onRegister() {
this.$router.push({name: 'FirRegist'})
},
onLogin() {
this.$router.push({name: 'FirLogin'})
},
get_auth_code() {
loginFun(data => {
if (data.code === 1000) {
this.cptch = data.data;
this.register_enable = data.data.register_enable;
this.form.authcode = '';
} else {
this.$message({
message: data.msg,
type: 'error'
});
}
}, {
"methods": "GET",
"data": {}
});
},
},
mounted() {
this.get_auth_code();
}, created() {
}
}
</script>
<style scoped>
.el-container {
margin: 10px auto;
width: 1266px;
}
.el-header {
margin-top: 13%;
}
.el-form {
max-width: 360px;
margin: 0 auto;
}
.el-form-item .el-button {
max-width: 360px;
/*padding: 16px 20px;*/
width: 100%;
position: relative;
height: 50px;
}
.el-header {
text-align: center;
overflow: hidden;
margin-bottom: 50px
}
.el-header div span {
font-size: 24px;
display: inline-block;
vertical-align: middle;
padding: 8px 40px
}
.el-header div:before, .el-header div:after {
content: ' ';
display: inline-block;
vertical-align: middle;
width: 50%;
height: 1px;
background-color: #babfc3;
margin: 0 0 0 -50%
}
.el-header div {
text-align: center
}
.el-header div:after {
margin: 0 -50% 0 0
}
</style>

@ -52,7 +52,7 @@
<el-input :value="currentapp.domain_name" clearable <el-input :value="currentapp.domain_name" clearable
style="width: 60%;margin-right: 10px" prefix-icon="el-icon-download" style="width: 60%;margin-right: 10px" prefix-icon="el-icon-download"
:placeholder="defualt_dtitle"/> :placeholder="defualt_dtitle"/>
<el-button @click="bind_domain_sure=true">保存</el-button> <el-button @click="bind_domain_sure=true">设置域名</el-button>
</el-form-item> </el-form-item>
<el-form-item label-width="200px" label="微信内访问简易模式"> <el-form-item label-width="200px" label="微信内访问简易模式">

@ -166,7 +166,9 @@
if (data.code === 1000) { if (data.code === 1000) {
if (this.active++ > 2) this.active = 3; if (this.active++ > 2) this.active = 3;
this.bind_status = true; this.bind_status = true;
if (!this.app_id) {
this.$store.dispatch("dodomainshow", false); this.$store.dispatch("dodomainshow", false);
}
} else { } else {
if (data.code === 1004) { if (data.code === 1004) {
this.active = 1; this.active = 1;
@ -185,7 +187,9 @@
this.bind_status = false; this.bind_status = false;
this.active = 1; this.active = 1;
this.$message.success("解除绑定成功 "); this.$message.success("解除绑定成功 ");
if (!this.app_id) {
this.$store.dispatch("dodomainshow", true); this.$store.dispatch("dodomainshow", true);
}
} else { } else {
this.$message.error("解除绑定失败 " + data.msg) this.$message.error("解除绑定失败 " + data.msg)
} }

@ -145,6 +145,12 @@ const router = new VueRouter({
name: 'FirRegist', name: 'FirRegist',
component: () => import("@/components/FirRegist"), component: () => import("@/components/FirRegist"),
},
{
path: '/reset/pwd',
name: 'FirResetPwd',
component: () => import("@/components/FirResetPwd"),
}, },
{ {
path: '/:short', path: '/:short',

@ -4,7 +4,7 @@
# author: NinEveN # author: NinEveN
# date: 2021/4/16 # date: 2021/4/16
import os, re import os, re, time
from fir_ser.settings import SUPER_SIGN_ROOT from fir_ser.settings import SUPER_SIGN_ROOT
from api.models import AppReleaseInfo, UserDomainInfo from api.models import AppReleaseInfo, UserDomainInfo
from api.utils.app.randomstrings import make_app_uuid from api.utils.app.randomstrings import make_app_uuid
@ -106,17 +106,28 @@ def format_storage_selection(storage_info_list, storage_choice_list):
def get_cname_from_domain(domain): def get_cname_from_domain(domain):
dns_list = [
["8.8.8.8", "8.8.4.4"],
["119.29.29.29", "114.114.114.114"],
["223.5.5.5", "223.6.6.6"],
]
dns_resolver = Resolver() dns_resolver = Resolver()
dns_resolver.nameservers = ["8.8.8.8", "8.8.4.4"]
domain = domain.lower().strip() domain = domain.lower().strip()
count = 3
while count:
try: try:
dns_resolver.nameservers = dns_list[len(dns_list) - count]
return dns_resolver.query(domain, 'CNAME')[0].to_text() return dns_resolver.query(domain, 'CNAME')[0].to_text()
except Exception: except Exception as e:
logger.error("dns %s resolve %s failed Exception:%s" % (dns_resolver.nameservers, domain, e))
count -= 1
time.sleep(0.3)
if count <= 0:
return str(None) return str(None)
def get_user_domain_name(obj): def get_user_domain_name(obj):
domain_obj = UserDomainInfo.objects.filter(user_id=obj, is_enable=True).first() domain_obj = UserDomainInfo.objects.filter(user_id=obj, is_enable=True, app_id=None).first()
if domain_obj: if domain_obj:
return domain_obj.domain_name return domain_obj.domain_name
return '' return ''

@ -18,7 +18,7 @@ from rest_framework.pagination import PageNumberPagination
import logging import logging
from fir_ser.settings import SERVER_DOMAIN from fir_ser.settings import SERVER_DOMAIN
from api.utils.utils import delete_local_files, delete_app_screenshots_files from api.utils.utils import delete_local_files, delete_app_screenshots_files
from api.utils.baseutils import is_valid_domain, get_user_domain_name from api.utils.baseutils import is_valid_domain, get_user_domain_name, get_app_domain_name
from api.base_views import app_delete from api.base_views import app_delete
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -211,8 +211,7 @@ class AppInfoView(APIView):
apps_obj.supersign_limit_number) apps_obj.supersign_limit_number)
apps_obj.isshow = data.get("isshow", apps_obj.isshow) apps_obj.isshow = data.get("isshow", apps_obj.isshow)
if get_user_domain_name(request.user) or ( if get_user_domain_name(request.user) or get_app_domain_name(apps_obj):
apps_obj.domain_name and len(apps_obj.domain_name) > 3):
apps_obj.wxeasytype = data.get("wxeasytype", apps_obj.wxeasytype) apps_obj.wxeasytype = data.get("wxeasytype", apps_obj.wxeasytype)
else: else:
apps_obj.wxeasytype = 1 apps_obj.wxeasytype = 1

@ -20,7 +20,7 @@ from api.utils.serializer import AppsShortSerializer
from api.models import Apps, AppReleaseInfo, APPToDeveloper, APPSuperSignUsedInfo from api.models import Apps, AppReleaseInfo, APPToDeveloper, APPSuperSignUsedInfo
from django.http import FileResponse from django.http import FileResponse
import logging import logging
from api.utils.baseutils import get_profile_full_path from api.utils.baseutils import get_profile_full_path, get_app_domain_name
from api.utils.throttle import VisitShortThrottle, InstallShortThrottle from api.utils.throttle import VisitShortThrottle, InstallShortThrottle
logger = logging.getLogger(__file__) logger = logging.getLogger(__file__)
@ -181,7 +181,7 @@ class ShortDownloadView(APIView):
"storage": Storage(app_obj.user_id)}) "storage": Storage(app_obj.user_id)})
res.data = app_serializer.data res.data = app_serializer.data
res.udid = udid res.udid = udid
res.domain_name = get_redirect_server_domain(request, app_obj.user_id, app_obj.domain_name) res.domain_name = get_redirect_server_domain(request, app_obj.user_id, get_app_domain_name(app_obj))
return Response(res.dict) return Response(res.dict)
# key的设置 # key的设置

@ -30,6 +30,16 @@ def get_register_type():
return REGISTER.get("register_type") return REGISTER.get("register_type")
def reset_user_pwd(user, surepassword, oldpassword=''):
if user is not None:
user.set_password(surepassword)
user.save()
logger.info("user:%s change password success,old %s new %s" % (user, oldpassword, surepassword))
for token_obj in Token.objects.filter(user=user):
cache.delete(token_obj.access_token)
token_obj.delete()
def GetAuthenticate(target, password, act, allow_type): def GetAuthenticate(target, password, act, allow_type):
user_obj = None user_obj = None
if act == 'email' and allow_type[act]: if act == 'email' and allow_type[act]:
@ -198,6 +208,24 @@ class LoginView(APIView):
login_type = receive.get("login_type", None) login_type = receive.get("login_type", None)
if login_auth_failed("get", username): if login_auth_failed("get", username):
if login_type == 'reset':
if is_valid_email(username):
user_obj = UserInfo.objects.filter(email=username).first()
if user_obj:
password = get_random_username()[:16]
msg = '您的新密码为 %s 请用新密码登录之后,及时修改密码' % password
a, b = get_sender_email_token('email', username, 'msg', msg)
if a and b:
reset_user_pwd(user_obj, password, oldpassword='')
login_auth_failed("del", username)
else:
response.code = 1002
response.msg = "邮箱不存在"
else:
response.code = 1003
response.msg = "无效邮箱"
return Response(response.dict)
password = receive.get("password") password = receive.get("password")
user = GetAuthenticate(username, password, login_type, get_login_type()) user = GetAuthenticate(username, password, login_type, get_login_type())
logger.info("username:%s password:%s" % (username, password)) logger.info("username:%s password:%s" % (username, password))

Loading…
Cancel
Save