from fastapi import FastAPI, Response, Cookie from datetime import datetime import aiohttp import json from . import db from typing import Annotated from .cfg import config FL_SERVER = config["flarum"]["fl_server"] FL_APIKEY = config["flarum"]["fl_apikey"] def main(app: FastAPI, ROOT: str, apikeys: dict): async def check_apikey(tkn: str): res = apikeys.get(tkn, None) if (res is None): return "" if (res[1] < datetime.now()): del apikeys[tkn] return "" return res[0] @app.get("/app/flarum/patch.js") async def patchjson(): return Response(""" setTimeout(function() { var signup_obj = document.getElementsByClassName( "item-logIn")[0] if(signup_obj!=undefined){ signup_obj.style.display = "none"; } var btn_obj=document.getElementsByClassName("item-logIn")[0] if(btn_obj != undefined){ btn_obj.innerHTML = "注册/登录"} }, 500); setTimeout(function() { var hashs = window.location.hash if(hashs!==""){ var exp=/(?<=#access_token\\=).*(?=&token_type)/g var res = hashs.match(exp) if(res!=null){ var key = res[0] var xhr = new XMLHttpRequest() var csrf = JSON.parse(document.getElementById("flarum-json-payload").innerText)["session"]["csrfToken"] 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") async def login(apikey: str, csrftoken: str, resp: Response, flarum_session: Annotated[str | None, Cookie()] = None): username = await check_apikey(apikey) if (username == ""): return {"msg": "token无效"} if (flarum_session is None): return {"msg": "session无效"} user_passwd = await db.get_user_passwd(username) data_obj = {"data": {"attributes": { "username": username, "email": await db.get_email(username), "isEmailConfirmed": True, "password": user_passwd } } } headers = { "Authorization": f"Token {FL_APIKEY}", "Content-Type": "application/json;charset=utf-8" } async with aiohttp.ClientSession() as session: async with session.post(FL_SERVER+"/api/users", headers=headers, data=json.dumps(data_obj)) as response: if (response.status != 201): pass data_obj = { "identification": username, "password": user_passwd, "remember": True } headers = { "Authorization": f"Token {FL_APIKEY}", "Content-Type": "application/json;charset=utf-8", "Cookie": f"flarum_session={flarum_session}", "X-Csrf-Token": csrftoken } async with aiohttp.ClientSession() as session: async with session.post(FL_SERVER+"/login", headers=headers, data=json.dumps(data_obj)) as response: cookies = response.cookies flarum_session = cookies.get('flarum_session') flarum_remember = cookies.get('flarum_remember') resp.set_cookie("flarum_session", flarum_session) resp.set_cookie("flarum_remember", flarum_remember) return {"msg": ""}