This commit is contained in:
felinae98 2021-09-24 15:48:53 +08:00
parent 31c5e283ba
commit dce58580f2
No known key found for this signature in database
GPG Key ID: 00C8B010587FF610
16 changed files with 370 additions and 20 deletions

View File

@ -17,6 +17,7 @@
"axios": "^0.21.4", "axios": "^0.21.4",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^5.3.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"typescript": "^4.1.2", "typescript": "^4.1.2",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1"
@ -44,5 +45,8 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"@types/react-router-dom": "^5.3.0"
} }
} }

View File

@ -1,9 +1,11 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import './App.css'; import './App.css';
import { LoginContext, loginContextDefault, GlobalConfContext } from './utils/context'; import { LoginContext, loginContextDefault, GlobalConfContext } from './utils/context';
import { LoginStatus, GlobalConf } from './utils/type'; import { LoginStatus, GlobalConf } from './utils/type';
import { Admin } from './pages/admin'; import { Admin } from './pages/admin';
import { getGlobalConf } from './api/config'; import { getGlobalConf } from './api/config';
import { Auth } from './pages/auth';
import 'antd/dist/antd.css'; import 'antd/dist/antd.css';
@ -15,7 +17,9 @@ function LoginSwitch() {
return ( return (
<div> <div>
not login not login
<button onClick={() => save({login: true, type: 'admin', name: ''})}>1</button> <button onClick={() => save({
login: true, type: 'admin', name: '', id: '123', token: ''
})}>1</button>
</div> </div>
) )
} }
@ -35,9 +39,18 @@ function App() {
}, []); }, []);
return ( return (
<LoginContext.Provider value={{login: loginStatus, save}}> <LoginContext.Provider value={{login: loginStatus, save}}>
<GlobalConfContext.Provider value={globalConf}> <GlobalConfContext.Provider value={globalConf}>
<LoginSwitch /> <Router>
</GlobalConfContext.Provider> <Switch>
<Route path="/auth/:code">
<Auth />
</Route>
<Route path="/admin/">
<LoginSwitch />
</Route>
</Switch>
</Router>
</GlobalConfContext.Provider>
</LoginContext.Provider> </LoginContext.Provider>
); );
} }

View File

@ -1,9 +1,13 @@
import axios from "axios"; import axios from "axios";
import { GlobalConf } from "../utils/type"; import { GlobalConf, TokenResp } from "../utils/type";
import { baseUrl } from './utils';
const baseUrl = '/hk_reporter/api/'
export async function getGlobalConf(): Promise<GlobalConf> { export async function getGlobalConf(): Promise<GlobalConf> {
const res = await axios.get<GlobalConf>(`${baseUrl}global_conf`); const res = await axios.get<GlobalConf>(`${baseUrl}global_conf`);
return res.data; return res.data;
} }
export async function auth(token: string): Promise<TokenResp> {
const res = await axios.get<TokenResp>(`${baseUrl}auth`, {params: {token}});
return res.data;
}

View File

@ -0,0 +1,21 @@
import axios from "axios";
// import { useContext } from 'react';
// import { LoginContext } from "../utils/context";
export const baseUrl = '/hk_reporter/api/'
// const loginStatus = useContext(LoginContext);
axios.interceptors.request.use(function (config) {
if (config.url && config.url.startsWith(baseUrl) && config.url !== `${baseUrl}auth`
&& config.url !== `${baseUrl}global_conf`) {
const token = sessionStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
} else {
throw new axios.Cancel('User not login');
}
}
return config;
}, function (error) {
return Promise.reject(error);
})

View File

@ -0,0 +1,27 @@
import React, {useContext, useEffect, useState} from "react";
import { useParams } from "react-router";
import { auth } from '../api/config';
import { LoginContext } from '../utils/context';
import { Redirect } from 'react-router-dom'
interface AuthParam {
code: string
}
export function Auth() {
const { code } = useParams<AuthParam>();
const [ content, contentUpdate ] = useState(<div>Logining...</div>);
const { save } = useContext(LoginContext);
useEffect(() => {
const loginFun = async () => {
const resp = await auth(code);
if (resp.status === 200) {
save({login: true, type: resp.type, name: resp.name, id: resp.id, token: resp.token});
contentUpdate(_ => <Redirect to={{pathname: '/admin'}} />);
sessionStorage.setItem('token', resp.token);
} else {
contentUpdate(_ => <div></div>);
}
}
loginFun();
}, [])
return content;
}

View File

@ -5,7 +5,10 @@ export const loginContextDefault: LoginContextType = {
login: { login: {
login: false, login: false,
type: '', type: '',
name: '' name: '',
id: '123',
// groups: [],
token: ''
}, },
save: () => {} save: () => {}
}; };

View File

@ -1,7 +1,15 @@
interface QQGroup {
id: string,
name: string,
}
export interface LoginStatus { export interface LoginStatus {
login: boolean login: boolean
type: String type: string
name: String name: string
id: string
// groups: Array<QQGroup>
token: string
} }
export type LoginContextType = { export type LoginContextType = {
@ -10,10 +18,10 @@ export type LoginContextType = {
} }
export interface SubscribeConfig { export interface SubscribeConfig {
platform: String platform: string
target?: String target?: string
catetories: Array<number> catetories: Array<number>
tags: Array<String> tags: Array<string>
} }
export interface GlobalConf { export interface GlobalConf {
@ -27,3 +35,11 @@ export interface PlatformConfig {
platformName: string, platformName: string,
hasTarget: boolean hasTarget: boolean
} }
export interface TokenResp {
status: number,
token: string,
type: string,
id: string
name: string
}

View File

@ -1191,7 +1191,7 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.15.4" version "7.15.4"
resolved "https://registry.nlark.com/@babel/runtime/download/@babel/runtime-7.15.4.tgz?cache=0&sync_timestamp=1630618914695&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" resolved "https://registry.nlark.com/@babel/runtime/download/@babel/runtime-7.15.4.tgz?cache=0&sync_timestamp=1630618914695&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
integrity sha1-/RfRa/34eObdAtGXU6OfqKjZyEo= integrity sha1-/RfRa/34eObdAtGXU6OfqKjZyEo=
@ -1844,6 +1844,11 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/history@*":
version "4.7.9"
resolved "https://registry.nlark.com/@types/history/download/@types/history-4.7.9.tgz#1cfb6d60ef3822c589f18e70f8b12f9a28ce8724"
integrity sha1-HPttYO84IsWJ8Y5w+LEvmijOhyQ=
"@types/html-minifier-terser@^5.0.0": "@types/html-minifier-terser@^5.0.0":
version "5.1.2" version "5.1.2"
resolved "https://registry.nlark.com/@types/html-minifier-terser/download/@types/html-minifier-terser-5.1.2.tgz?cache=0&sync_timestamp=1631043806613&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" resolved "https://registry.nlark.com/@types/html-minifier-terser/download/@types/html-minifier-terser-5.1.2.tgz?cache=0&sync_timestamp=1631043806613&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57"
@ -1941,6 +1946,23 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-router-dom@^5.3.0":
version "5.3.0"
resolved "https://registry.nlark.com/@types/react-router-dom/download/@types/react-router-dom-5.3.0.tgz?cache=0&sync_timestamp=1632253524133&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Freact-router-dom%2Fdownload%2F%40types%2Freact-router-dom-5.3.0.tgz#8c4e0aa0ccaf638ba965829ad29a10ac3cbe2212"
integrity sha1-jE4KoMyvY4upZYKa0poQrDy+IhI=
dependencies:
"@types/history" "*"
"@types/react" "*"
"@types/react-router" "*"
"@types/react-router@*":
version "5.1.16"
resolved "https://registry.nlark.com/@types/react-router/download/@types/react-router-5.1.16.tgz?cache=0&sync_timestamp=1629709375756&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Freact-router%2Fdownload%2F%40types%2Freact-router-5.1.16.tgz#f3ba045fb96634e38b21531c482f9aeb37608a99"
integrity sha1-87oEX7lmNOOLIVMcSC+a6zdgipk=
dependencies:
"@types/history" "*"
"@types/react" "*"
"@types/react@*", "@types/react@^17.0.0": "@types/react@*", "@types/react@^17.0.0":
version "17.0.22" version "17.0.22"
resolved "https://registry.nlark.com/@types/react/download/@types/react-17.0.22.tgz?cache=0&sync_timestamp=1632119536601&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-17.0.22.tgz#c80d1d0e87fe953bae3ab273bef451dea1a6291b" resolved "https://registry.nlark.com/@types/react/download/@types/react-17.0.22.tgz?cache=0&sync_timestamp=1632119536601&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-17.0.22.tgz#c80d1d0e87fe953bae3ab273bef451dea1a6291b"
@ -5672,6 +5694,18 @@ hex-color-regex@^1.1.0:
resolved "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" resolved "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4= integrity sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4=
history@^4.9.0:
version "4.10.1"
resolved "https://registry.nlark.com/history/download/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
integrity sha1-MzcaZeOoOyZ0NOKz87G0xYqtTPM=
dependencies:
"@babel/runtime" "^7.1.2"
loose-envify "^1.2.0"
resolve-pathname "^3.0.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
value-equal "^1.0.1"
hmac-drbg@^1.0.1: hmac-drbg@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" resolved "https://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@ -5681,6 +5715,13 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0" minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.1.0:
version "3.3.2"
resolved "https://registry.npm.taobao.org/hoist-non-react-statics/download/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha1-7OCsr3HWLClpwuxZ/v9CpLGoW0U=
dependencies:
react-is "^16.7.0"
hoopy@^0.1.4: hoopy@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.nlark.com/hoopy/download/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" resolved "https://registry.nlark.com/hoopy/download/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
@ -6372,6 +6413,11 @@ is-wsl@^2.1.1, is-wsl@^2.2.0:
dependencies: dependencies:
is-docker "^2.0.0" is-docker "^2.0.0"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@ -7226,7 +7272,7 @@ loglevel@^1.6.8:
resolved "https://registry.nlark.com/loglevel/download/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" resolved "https://registry.nlark.com/loglevel/download/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
integrity sha1-AF/eL15uRwaPk1/yhXPhJe9y8Zc= integrity sha1-AF/eL15uRwaPk1/yhXPhJe9y8Zc=
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" resolved "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8= integrity sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=
@ -7437,6 +7483,14 @@ min-indent@^1.0.0:
resolved "https://registry.npm.taobao.org/min-indent/download/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" resolved "https://registry.npm.taobao.org/min-indent/download/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha1-pj9oFnOzBXH76LwlaGrnRu76mGk= integrity sha1-pj9oFnOzBXH76LwlaGrnRu76mGk=
mini-create-react-context@^0.4.0:
version "0.4.1"
resolved "https://registry.npm.taobao.org/mini-create-react-context/download/mini-create-react-context-0.4.1.tgz?cache=0&sync_timestamp=1603390284123&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmini-create-react-context%2Fdownload%2Fmini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e"
integrity sha1-ByFxVhv9ySLaCKYMIZekl8wtHV4=
dependencies:
"@babel/runtime" "^7.12.1"
tiny-warning "^1.0.3"
mini-css-extract-plugin@0.11.3: mini-css-extract-plugin@0.11.3:
version "0.11.3" version "0.11.3"
resolved "https://registry.nlark.com/mini-css-extract-plugin/download/mini-css-extract-plugin-0.11.3.tgz#15b0910a7f32e62ffde4a7430cfefbd700724ea6" resolved "https://registry.nlark.com/mini-css-extract-plugin/download/mini-css-extract-plugin-0.11.3.tgz#15b0910a7f32e62ffde4a7430cfefbd700724ea6"
@ -8202,6 +8256,13 @@ path-to-regexp@0.1.7:
resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
path-to-regexp@^1.7.0:
version "1.8.0"
resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
integrity sha1-iHs7qdhDk+h6CgufTLdWGYtTVIo=
dependencies:
isarray "0.0.1"
path-type@^3.0.0: path-type@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" resolved "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
@ -9074,7 +9135,7 @@ prompts@^2.0.1:
kleur "^3.0.3" kleur "^3.0.3"
sisteransi "^1.0.5" sisteransi "^1.0.5"
prop-types@^15.7.2: prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2" version "15.7.2"
resolved "https://registry.npm.taobao.org/prop-types/download/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" resolved "https://registry.npm.taobao.org/prop-types/download/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha1-UsQedbjIfnK52TYOAga5ncv/psU= integrity sha1-UsQedbjIfnK52TYOAga5ncv/psU=
@ -9633,7 +9694,7 @@ react-error-overlay@^6.0.9:
resolved "https://registry.nlark.com/react-error-overlay/download/react-error-overlay-6.0.9.tgz?cache=0&sync_timestamp=1630519095858&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-error-overlay%2Fdownload%2Freact-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" resolved "https://registry.nlark.com/react-error-overlay/download/react-error-overlay-6.0.9.tgz?cache=0&sync_timestamp=1630519095858&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-error-overlay%2Fdownload%2Freact-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
integrity sha1-PHQwEMk1lgjDdezWvHbzXZOZWwo= integrity sha1-PHQwEMk1lgjDdezWvHbzXZOZWwo=
react-is@^16.12.0, react-is@^16.8.1: react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1" version "16.13.1"
resolved "https://registry.nlark.com/react-is/download/react-is-16.13.1.tgz?cache=0&sync_timestamp=1631895385110&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-is%2Fdownload%2Freact-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.nlark.com/react-is/download/react-is-16.13.1.tgz?cache=0&sync_timestamp=1631895385110&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-is%2Fdownload%2Freact-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ= integrity sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=
@ -9648,6 +9709,35 @@ react-refresh@^0.8.3:
resolved "https://registry.nlark.com/react-refresh/download/react-refresh-0.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-refresh%2Fdownload%2Freact-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" resolved "https://registry.nlark.com/react-refresh/download/react-refresh-0.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-refresh%2Fdownload%2Freact-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
integrity sha1-ch1GV2ctQAxePHXQY8SoX7LV1o8= integrity sha1-ch1GV2ctQAxePHXQY8SoX7LV1o8=
react-router-dom@^5.3.0:
version "5.3.0"
resolved "https://registry.nlark.com/react-router-dom/download/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363"
integrity sha1-2hv7U1oOiacSqTuX3Xb0etHzI2M=
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
loose-envify "^1.3.1"
prop-types "^15.6.2"
react-router "5.2.1"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-router@5.2.1:
version "5.2.1"
resolved "https://registry.nlark.com/react-router/download/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d"
integrity sha1-TS5OnVrpQlCRhFuNvG2dJ2I5d00=
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
hoist-non-react-statics "^3.1.0"
loose-envify "^1.3.1"
mini-create-react-context "^0.4.0"
path-to-regexp "^1.7.0"
prop-types "^15.6.2"
react-is "^16.6.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-scripts@4.0.3: react-scripts@4.0.3:
version "4.0.3" version "4.0.3"
resolved "https://registry.nlark.com/react-scripts/download/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345" resolved "https://registry.nlark.com/react-scripts/download/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345"
@ -9975,6 +10065,11 @@ resolve-from@^5.0.0:
resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha1-w1IlhD3493bfIcV1V7wIfp39/Gk= integrity sha1-w1IlhD3493bfIcV1V7wIfp39/Gk=
resolve-pathname@^3.0.0:
version "3.0.0"
resolved "https://registry.nlark.com/resolve-pathname/download/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
integrity sha1-mdAiJNPPJjaJvsuzk7xWAxMCXc0=
resolve-url-loader@^3.1.2: resolve-url-loader@^3.1.2:
version "3.1.4" version "3.1.4"
resolved "https://registry.nlark.com/resolve-url-loader/download/resolve-url-loader-3.1.4.tgz#3c16caebe0b9faea9c7cc252fa49d2353c412320" resolved "https://registry.nlark.com/resolve-url-loader/download/resolve-url-loader-3.1.4.tgz#3c16caebe0b9faea9c7cc252fa49d2353c412320"
@ -11083,6 +11178,16 @@ timsort@^0.3.0:
resolved "https://registry.nlark.com/timsort/download/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" resolved "https://registry.nlark.com/timsort/download/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-invariant@^1.0.2:
version "1.1.0"
resolved "https://registry.npm.taobao.org/tiny-invariant/download/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
integrity sha1-Y0xfjv3CdxS384bDXmdgmR0jCHU=
tiny-warning@^1.0.0, tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.npm.taobao.org/tiny-warning/download/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha1-lKMNtFPfTGQ9D9VmBg1gqHXYR1Q=
tmpl@1.0.x: tmpl@1.0.x:
version "1.0.5" version "1.0.5"
resolved "https://registry.nlark.com/tmpl/download/tmpl-1.0.5.tgz?cache=0&sync_timestamp=1630997323959&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftmpl%2Fdownload%2Ftmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" resolved "https://registry.nlark.com/tmpl/download/tmpl-1.0.5.tgz?cache=0&sync_timestamp=1630997323959&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftmpl%2Fdownload%2Ftmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
@ -11505,6 +11610,11 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0" spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0" spdx-expression-parse "^3.0.0"
value-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.nlark.com/value-equal/download/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
integrity sha1-Hgt5THNMXAyt4XnEN9NW2TGjTWw=
vary@~1.1.2: vary@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"

44
poetry.lock generated
View File

@ -245,6 +245,22 @@ type = "legacy"
url = "https://mirrors.aliyun.com/pypi/simple" url = "https://mirrors.aliyun.com/pypi/simple"
reference = "aliyun" reference = "aliyun"
[[package]]
name = "expiringdict"
version = "1.2.1"
description = "Dictionary with auto-expiring values for caching purposes"
category = "main"
optional = false
python-versions = "*"
[package.extras]
tests = ["dill", "coverage", "coveralls", "mock", "nose"]
[package.source]
type = "legacy"
url = "https://mirrors.aliyun.com/pypi/simple"
reference = "aliyun"
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.68.1" version = "0.68.1"
@ -798,6 +814,25 @@ type = "legacy"
url = "https://mirrors.aliyun.com/pypi/simple" url = "https://mirrors.aliyun.com/pypi/simple"
reference = "aliyun" reference = "aliyun"
[[package]]
name = "pyjwt"
version = "2.1.0"
description = "JSON Web Token implementation in Python"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
crypto = ["cryptography (>=3.3.1,<4.0.0)"]
dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1,<4.0.0)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"]
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
[package.source]
type = "legacy"
url = "https://mirrors.aliyun.com/pypi/simple"
reference = "aliyun"
[[package]] [[package]]
name = "pyparsing" name = "pyparsing"
version = "2.4.7" version = "2.4.7"
@ -1266,7 +1301,7 @@ reference = "aliyun"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "b1d377eac7e32ca08bd703b2f2a3094d6b72dead8c731902d38762da3b1dd7a2" content-hash = "e485e40f6187e8125f78e7595072280c2a67830ef8cfc3718ecd5f89c0d1064a"
[metadata.files] [metadata.files]
anyio = [ anyio = [
@ -1379,6 +1414,9 @@ decorator = [
{file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"}, {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"},
{file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"}, {file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"},
] ]
expiringdict = [
{file = "expiringdict-1.2.1.tar.gz", hash = "sha256:fe2ba427220425c3c8a3d29f6d2e2985bcee323f8bcd4021e68ebefbd90d8250"},
]
fastapi = [ fastapi = [
{file = "fastapi-0.68.1-py3-none-any.whl", hash = "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23"}, {file = "fastapi-0.68.1-py3-none-any.whl", hash = "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23"},
{file = "fastapi-0.68.1.tar.gz", hash = "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d"}, {file = "fastapi-0.68.1.tar.gz", hash = "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d"},
@ -1589,6 +1627,10 @@ pygments = [
pygtrie = [ pygtrie = [
{file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"}, {file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"},
] ]
pyjwt = [
{file = "PyJWT-2.1.0-py3-none-any.whl", hash = "sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1"},
{file = "PyJWT-2.1.0.tar.gz", hash = "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130"},
]
pyparsing = [ pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},

View File

@ -29,6 +29,8 @@ pyppeteer = "^0.2.5"
pillow = "^8.1.0" pillow = "^8.1.0"
nonebot-adapter-cqhttp = "^2.0.0-alpha.15" nonebot-adapter-cqhttp = "^2.0.0-alpha.15"
apscheduler = "^3.7.0" apscheduler = "^3.7.0"
expiringdict = "^1.2.1"
pyjwt = "^2.1.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
ipdb = "^0.13.4" ipdb = "^0.13.4"

View File

@ -2,15 +2,23 @@ import importlib
from pathlib import Path from pathlib import Path
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from nonebot import get_driver from nonebot import get_driver, on_command
import nonebot
from nonebot.adapters.cqhttp.bot import Bot
from nonebot.adapters.cqhttp.event import GroupMessageEvent, PrivateMessageEvent
from nonebot.drivers.fastapi import Driver from nonebot.drivers.fastapi import Driver
from nonebot.log import logger from nonebot.log import logger
from nonebot.rule import to_me
from nonebot.typing import T_State
import socketio import socketio
from .api import test, get_global_conf from .api import test, get_global_conf, auth
from .token_manager import token_manager as tm
from ..plugin_config import plugin_config
URL_BASE = '/hk_reporter/' URL_BASE = '/hk_reporter/'
GLOBAL_CONF_URL = f'{URL_BASE}api/global_conf' GLOBAL_CONF_URL = f'{URL_BASE}api/global_conf'
AUTH_URL = f'{URL_BASE}api/auth'
TEST_URL = f'{URL_BASE}test' TEST_URL = f'{URL_BASE}test'
sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*") sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*")
@ -21,6 +29,7 @@ def register_router_fastapi(driver: Driver, socketio):
static_path = str((Path(__file__).parent / "dist").resolve()) static_path = str((Path(__file__).parent / "dist").resolve())
app.get(TEST_URL)(test) app.get(TEST_URL)(test)
app.get(GLOBAL_CONF_URL)(get_global_conf) app.get(GLOBAL_CONF_URL)(get_global_conf)
app.get(AUTH_URL)(auth)
app.mount(URL_BASE, StaticFiles(directory=static_path, html=True), name="hk_reporter") app.mount(URL_BASE, StaticFiles(directory=static_path, html=True), name="hk_reporter")
def init(): def init():
@ -39,3 +48,15 @@ def init():
f"<b><u>http://{host}:{port}{URL_BASE}</u></b>") f"<b><u>http://{host}:{port}{URL_BASE}</u></b>")
init() init()
get_token = on_command('后台管理', rule=to_me(), priority=5)
@get_token.handle()
async def send_token(bot: "Bot", event: PrivateMessageEvent, state: T_State):
driver = nonebot.get_driver()
superusers = driver.config.superusers
if event.get_user_id() not in superusers:
await get_token.finish('你不是管理员')
else:
token = tm.get_user_token((event.get_user_id(), event.sender.nickname))
await get_token.finish(f'请访问: {plugin_config.hk_reporter_outer_url}auth/{token}')

View File

@ -1,4 +1,9 @@
from ..platform import platform_manager from ..platform import platform_manager
from .token_manager import token_manager
from .jwt import pack_jwt
from ..config import Config
import nonebot
from nonebot.adapters.cqhttp.bot import Bot
async def test(): async def test():
return {"status": 200, "text": "test"} return {"status": 200, "text": "test"}
@ -15,3 +20,37 @@ async def get_global_conf():
}) })
return { 'platformConf': res } return { 'platformConf': res }
async def auth(token: str):
if qq_tuple := token_manager.get_user(token):
qq, nickname = qq_tuple
bot = nonebot.get_bot()
assert(isinstance(bot, Bot))
groups = await bot.call_api('get_group_list')
if str(qq) in nonebot.get_driver().config.superusers:
jwt_obj = {
'id': str(qq),
'groups': list(map(
lambda info: {'id': info['group_id'], 'name': info['group_name']},
groups)),
}
ret_obj = {
'type': 'admin',
'name': nickname,
'id': str(qq),
'token': pack_jwt(jwt_obj)
}
return { 'status': 200, **ret_obj }
else:
return { 'status': 400, 'type': '', 'name': '', 'id': '', 'token': '' }
else:
return { 'status': 400, 'type': '', 'name': '', 'id': '', 'token': '' }
async def get_subs_info(jwt_obj: dict):
groups = jwt_obj['groups']
res = {}
for group in groups:
group_id = group['id']
config = Config()
subs = list(map(lambda sub: {'targetType': sub['target_type'], 'target': sub['target'], 'targetName': sub['target_name'], 'cats': sub['cats'], 'tags': sub['tags']},

View File

@ -0,0 +1,20 @@
import random
import string
from typing import Optional
import jwt
import datetime
_key = ''.join(random.SystemRandom().choice(string.ascii_letters) for _ in range(16))
def pack_jwt(obj: dict) -> str:
return jwt.encode(
{'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1), **obj},
_key, algorithm='HS256'
)
def load_jwt(token: str) -> Optional[dict]:
try:
return jwt.decode(token, _key, algorithm='HS256')
except:
return None

View File

@ -0,0 +1,24 @@
from typing import Optional
from expiringdict import ExpiringDict
import random
import string
class TokenManager:
def __init__(self):
self.token_manager = ExpiringDict(max_len=100, max_age_seconds=60*10)
def get_user(self, token: str) -> Optional[tuple]:
res = self.token_manager.get(token)
assert(res is None or isinstance(res, tuple))
return res
def save_user(self, token: str, qq: tuple) -> None:
self.token_manager[token] = qq
def get_user_token(self, qq: tuple) -> str:
token = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
self.save_user(token, qq)
return token
token_manager = TokenManager()

View File

@ -64,6 +64,9 @@ class Config(metaclass=Singleton):
if user_sub := self.user_target.get((query.user == user) & (query.user_type ==user_type)): if user_sub := self.user_target.get((query.user == user) & (query.user_type ==user_type)):
return user_sub['subs'] return user_sub['subs']
return [] return []
def get_all_subscribe(self):
return self.user_target
def del_subscribe(self, user, user_type, target, target_type): def del_subscribe(self, user, user_type, target, target_type):
user_query = Query() user_query = Query()

View File

@ -10,6 +10,7 @@ class PlugConfig(BaseSettings):
hk_reporter_use_local: bool = False hk_reporter_use_local: bool = False
hk_reporter_browser: str = '' hk_reporter_browser: str = ''
hk_reporter_init_filter: bool = True hk_reporter_init_filter: bool = True
hk_reporter_outer_url: str = 'http://localhost:8080/hk_reporter/'
class Config: class Config:
extra = 'ignore' extra = 'ignore'