Compare commits
2 Commits
a7c0a51b71
...
fd8564ecc2
Author | SHA1 | Date |
---|---|---|
cxykevin | fd8564ecc2 | |
cxykevin | 08b822fff8 |
|
@ -1,7 +1,7 @@
|
|||
from fastapi.security import OAuth2PasswordBearer
|
||||
from fastapi import FastAPI, Cookie, Response, Form
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from fastapi.responses import RedirectResponse
|
||||
from fastapi.responses import RedirectResponse, HTMLResponse
|
||||
from datetime import timedelta, datetime
|
||||
from contextlib import asynccontextmanager
|
||||
from . import db
|
||||
|
@ -72,7 +72,7 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
|||
def check_passwd(passwd: str):
|
||||
if (len(passwd) < 8):
|
||||
return 1
|
||||
pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$'
|
||||
pattern = r'^(?![a-zA-Z]+$)(?!\d+$)(?![^\da-zA-Z\s]+$).{8,40}$'
|
||||
|
||||
if re.match(pattern, passwd):
|
||||
return 0
|
||||
|
@ -150,12 +150,14 @@ async def login_callback(username: str = Form(), password: str = Form(), email:
|
|||
|
||||
|
||||
@app.get("/api/checkemail")
|
||||
async def login_callback(uid: str):
|
||||
async def checkemail(uid: str):
|
||||
if (uid not in emails):
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "不存在的注册id"})
|
||||
if (emails[uid][2] < datetime.now()):
|
||||
del emails[uid]
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "链接已过期"})
|
||||
if (emails[uid][1] == ""):
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "不存在的注册id"})
|
||||
if await db.create_user(emails[uid][0], emails[uid][1], emails[uid][3]) == 0:
|
||||
del emails[uid]
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "创建成功"})
|
||||
|
@ -164,6 +166,36 @@ async def login_callback(uid: str):
|
|||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "重复的用户名"})
|
||||
|
||||
|
||||
@app.get("/api/resetpasswd", response_class=HTMLResponse)
|
||||
async def resetpasswd(uid: str, response: Response):
|
||||
if (uid not in emails):
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "不存在的验证id"})
|
||||
if (emails[uid][2] < datetime.now()):
|
||||
del emails[uid]
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "链接已过期"})
|
||||
if (emails[uid][1] != ""):
|
||||
return templates.TemplateResponse("checkemail.html", {"request": {}, "msg": "不存在的注册id"})
|
||||
tokennow = await create_token(emails[uid][0])
|
||||
tkn = uuid.uuid4().hex
|
||||
apikeys[tkn] = tokens[tokennow]
|
||||
response.set_cookie("session", tokennow)
|
||||
return '<html><head><meta http-equiv="refresh" content="0;url=/user"><title>正在跳转</title></head><body>正在跳转</body></html>'
|
||||
|
||||
|
||||
@app.post("/api/send_resetpasswd")
|
||||
async def resetpasswd(username: str = Form()):
|
||||
if (await db.check_user(username)):
|
||||
email = await db.get_email(username)
|
||||
tkn = uuid.uuid4().hex
|
||||
emails[tkn] = (username, "", datetime.now() +
|
||||
timedelta(minutes=float(ACCESS_EMAIL_EXPIRE_MINUTES)), email)
|
||||
|
||||
email_send_lst.append((email, ROOT+"/api/resetpasswd?uid="+tkn))
|
||||
return {"msg": "验证邮件已发送到邮箱,请在10分钟内完成验证", "code": 0}
|
||||
else:
|
||||
return {"msg": "用户名不存在", "code": 1}
|
||||
|
||||
|
||||
@app.get("/api/getinfo")
|
||||
async def get_user_info(uid: str):
|
||||
username = await check_apikey(uid)
|
||||
|
@ -219,6 +251,11 @@ async def login(session: Annotated[str | None, Cookie()] = None):
|
|||
return templates.TemplateResponse("manage.html", {"request": {}})
|
||||
|
||||
|
||||
@app.get("/resetpasswd")
|
||||
async def resetpasswd(response: Response):
|
||||
return templates.TemplateResponse("resetpasswd.html", {"request": {}})
|
||||
|
||||
|
||||
@app.get("/manager/init")
|
||||
async def init(key: str):
|
||||
if (key != MANAGE_KEY):
|
||||
|
|
|
@ -27,15 +27,16 @@ def main(app: FastAPI, ROOT: str, apikeys: dict):
|
|||
return Response("""
|
||||
setTimeout(function() {
|
||||
var signup_obj = document.getElementsByClassName(
|
||||
"item-signUp")[0]
|
||||
"item-logIn")[0]
|
||||
if(signup_obj!=undefined){
|
||||
signup_obj.style.display = "none";
|
||||
}
|
||||
document.getElementsByClassName(
|
||||
"item-logIn")[0].innerHTML = "<a href='"""+ROOT+"""/login?redirect_url="+window.location.href+"'>登录/注册</a>";
|
||||
var btn_obj=document.getElementsByClassName("item-logIn")[0]
|
||||
if(btn_obj != undefined){
|
||||
btn_obj.innerHTML = "<a href='"""+ROOT+"""/login?redirect_url="+window.location.href+"'>注册/登录</a>"}
|
||||
}, 500);
|
||||
|
||||
|
||||
|
||||
setTimeout(function() {
|
||||
var hashs = window.location.hash
|
||||
if(hashs!==""){
|
||||
|
@ -45,17 +46,18 @@ def main(app: FastAPI, ROOT: str, apikeys: dict):
|
|||
var key = res[0]
|
||||
var xhr = new XMLHttpRequest()
|
||||
var csrf = JSON.parse(document.getElementById("flarum-json-payload").innerText)["session"]["csrfToken"]
|
||||
xhr.open('post','"""+FL_SERVER+"""/app/flarum/login?apikey='+key+'&csrftoken='+csrf);
|
||||
xhr.open('post','/app/flarum/login?apikey='+key+'&csrftoken='+csrf);
|
||||
xhr.onreadyStatechange = function () {
|
||||
if(xhr.readyState === 4 && xhr.status === 200) {
|
||||
console.log(xhr.responseText)
|
||||
window.location.hash = ""
|
||||
location.reload()
|
||||
}
|
||||
}
|
||||
xhr.send()
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
""", 200, None, media_type="application/javascript")
|
||||
|
||||
@app.post("/app/flarum/login")
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
label="用户名"></mdui-text-field>
|
||||
<mdui-text-field id="passwd" style="display:block;height:54px;width:90%;left:10%;margin:auto"
|
||||
label="密码" type="password" toggle-password></mdui-text-field>
|
||||
<mdui-button style="width:90%;margin-left:5%" variant="elevated"
|
||||
href="/resetpasswd">忘记密码?点我重置</mdui-button>
|
||||
<div style="position: absolute;bottom:20px;width:100%">
|
||||
<mdui-button id="loginbtn" style="width:calc(90% - 110px);margin-right:10px;margin-left:5%"
|
||||
onclick="logins()">登录</mdui-button>
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<html class="mdui-theme-auto">
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://learn.study-area.org.cn/theme/css/mdui.css">
|
||||
<script src="https://learn.study-area.org.cn/theme/js/mdui.global.js" type="text/javascript"></script>
|
||||
<link href="https://learn.study-area.org.cn/theme/css/icons.css" rel="stylesheet">
|
||||
<title>StuyAreaCN Accout System</title>
|
||||
<style>
|
||||
* {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body style="margin:0;padding:0;">
|
||||
<mdui-dialog id="dialog" close-on-overlay-click>
|
||||
</mdui-dialog>
|
||||
<mdui-layout style="height: 100%">
|
||||
<mdui-top-app-bar>
|
||||
<mdui-top-app-bar-title>StudyAreaCN</mdui-top-app-bar-title>
|
||||
</mdui-top-app-bar>
|
||||
|
||||
<mdui-navigation-drawer class="navi-drawer" id="toc-drawer">
|
||||
<mdui-list>
|
||||
<mdui-list-item end-icon="arrow_right" href="https://learn.study-area.org.cn"
|
||||
rounded>开始学习</mdui-list-item>
|
||||
<mdui-list-item end-icon="arrow_right" href="https://forum.study-area.org.cn"
|
||||
rounded>讨论区</mdui-list-item>
|
||||
<mdui-list-item end-icon="arrow_right"
|
||||
href="https://git.hmtsai.cn/study-area-cn/study-area-cn-homepage/" rounded>查看本站源码</mdui-list-item>
|
||||
</mdui-list>
|
||||
</mdui-navigation-drawer>
|
||||
|
||||
<mdui-layout-main style="height: 100%">
|
||||
<div style="width: 100%;height: 100%">
|
||||
<mdui-card
|
||||
style="width:30%;min-width:400px;height:60%;min-height:500px;margin: auto;display: block;transform: translate(-50%,-50%);left: 50%;top: 50%;position: absolute;"
|
||||
id="cards">
|
||||
<div class="header"
|
||||
style="font-size: 38px;font-weight: bold;text-align: center;line-height: 160px;">
|
||||
重置密码
|
||||
</div>
|
||||
<mdui-text-field id="username"
|
||||
style="display:block;height:54px;width:90%;margin:auto;margin-bottom: 16px"
|
||||
label="用户名"></mdui-text-field>
|
||||
<div style="position: absolute;bottom:20px;width:100%">
|
||||
<mdui-button id="loginbtn" style="width:90%;margin-right:10px;margin-left:5%"
|
||||
onclick="logins()">发送邮件</mdui-button>
|
||||
</div>
|
||||
</mdui-card>
|
||||
</div>
|
||||
</mdui-layout-main>
|
||||
</mdui-layout>
|
||||
<script>
|
||||
if (window.innerWidth > 800) {
|
||||
document.getElementById("cards").style.transform = "translateY(-50%)"
|
||||
document.getElementById("toc-drawer").setAttribute('open', true);
|
||||
}
|
||||
function logins() {
|
||||
document.getElementById("loginbtn").setAttribute('loading', "");
|
||||
const Http = new XMLHttpRequest();
|
||||
const url = '/api/send_resetpasswd';
|
||||
Http.open("POST", url);
|
||||
var formData = new FormData();
|
||||
formData.append('username', document.getElementById("username").value);
|
||||
Http.send(formData);
|
||||
|
||||
Http.addEventListener('loadend', () => {
|
||||
var ret = JSON.parse(Http.responseText)
|
||||
if (ret.msg == "") {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
window.location.href = "/login/?redirect_url=/user"
|
||||
} else {
|
||||
document.getElementById("dialog").innerHTML = ret.msg
|
||||
document.getElementById("dialog").setAttribute("open", "")
|
||||
}
|
||||
document.getElementById("loginbtn").removeAttribute('loading');
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue