support isop login
This commit is contained in:
20
package-lock.json
generated
20
package-lock.json
generated
@@ -1756,6 +1756,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
|
||||||
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
|
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
|
||||||
},
|
},
|
||||||
|
"charenc": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "http://registry.npm.taobao.org/charenc/download/charenc-0.0.2.tgz",
|
||||||
|
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||||
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
|
||||||
@@ -2216,6 +2221,11 @@
|
|||||||
"which": "1.3.1"
|
"which": "1.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"crypt": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "http://registry.npm.taobao.org/crypt/download/crypt-0.0.2.tgz",
|
||||||
|
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
|
||||||
|
},
|
||||||
"crypto-browserify": {
|
"crypto-browserify": {
|
||||||
"version": "3.12.0",
|
"version": "3.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
|
||||||
@@ -6562,6 +6572,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
|
||||||
"integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
|
"integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
|
||||||
},
|
},
|
||||||
|
"md5": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "http://registry.npm.taobao.org/md5/download/md5-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
|
||||||
|
"requires": {
|
||||||
|
"charenc": "0.0.2",
|
||||||
|
"crypt": "0.0.2",
|
||||||
|
"is-buffer": "1.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"md5.js": {
|
"md5.js": {
|
||||||
"version": "1.3.4",
|
"version": "1.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"copy-to-clipboard": "^3.0.8",
|
"copy-to-clipboard": "^3.0.8",
|
||||||
"load-script": "^1.0.0",
|
"load-script": "^1.0.0",
|
||||||
|
"md5": "^2.2.1",
|
||||||
"pressure": "^2.1.2",
|
"pressure": "^2.1.2",
|
||||||
"react": "^16.4.2",
|
"react": "^16.4.2",
|
||||||
"react-dom": "^16.4.2",
|
"react-dom": "^16.4.2",
|
||||||
|
|||||||
19
src/App.js
19
src/App.js
@@ -5,6 +5,20 @@ import {Sidebar} from './Sidebar';
|
|||||||
import {PressureHelper} from './PressureHelper';
|
import {PressureHelper} from './PressureHelper';
|
||||||
import {TokenCtx} from './UserAction';
|
import {TokenCtx} from './UserAction';
|
||||||
|
|
||||||
|
function TokenDeprecatedAlert(props) {
|
||||||
|
if(!props.token || props.token.startsWith('isop_')) // noinspection JSConstructorReturnsPrimitive
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return (
|
||||||
|
<div className="flow-item-row">
|
||||||
|
<div className="box box-tip flow-item box-danger">
|
||||||
|
<p>树洞已更换登录方式,您原来的登录状态已失效。</p>
|
||||||
|
<p>请按右上角的按钮,点“注销”,然后重新登录。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -62,14 +76,15 @@ class App extends Component {
|
|||||||
backgroundImage: 'url('+(localStorage['REPLACE_ERIRI_WITH_URL'] || 'static/eriri_bg.jpg')+')'
|
backgroundImage: 'url('+(localStorage['REPLACE_ERIRI_WITH_URL'] || 'static/eriri_bg.jpg')+')'
|
||||||
}} />
|
}} />
|
||||||
<Title show_sidebar={this.show_sidebar_bound} set_mode={this.set_mode_bound} />
|
<Title show_sidebar={this.show_sidebar_bound} set_mode={this.set_mode_bound} />
|
||||||
<div className="left-container">
|
|
||||||
<TokenCtx.Consumer>{(token)=>(
|
<TokenCtx.Consumer>{(token)=>(
|
||||||
|
<div className="left-container">
|
||||||
|
<TokenDeprecatedAlert token={token.value} />
|
||||||
<Flow key={this.state.flow_render_key} show_sidebar={this.show_sidebar_bound}
|
<Flow key={this.state.flow_render_key} show_sidebar={this.show_sidebar_bound}
|
||||||
mode={this.state.mode} search_text={this.state.search_text} token={token.value}
|
mode={this.state.mode} search_text={this.state.search_text} token={token.value}
|
||||||
/>
|
/>
|
||||||
)}</TokenCtx.Consumer>
|
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
|
)}</TokenCtx.Consumer>
|
||||||
<Sidebar do_close={()=>{
|
<Sidebar do_close={()=>{
|
||||||
this.setState({
|
this.setState({
|
||||||
sidebar_content: null,
|
sidebar_content: null,
|
||||||
|
|||||||
@@ -341,6 +341,7 @@ function FlowChunk(props) {
|
|||||||
{!!props.title && <TitleLine text={props.title} />}
|
{!!props.title && <TitleLine text={props.title} />}
|
||||||
{props.list.map((info,ind)=>(
|
{props.list.map((info,ind)=>(
|
||||||
<LazyLoad key={info.pid} offset={500} height="15em" once={true} >
|
<LazyLoad key={info.pid} offset={500} height="15em" once={true} >
|
||||||
|
<div>
|
||||||
{!!(props.deletion_detect && props.mode==='list' && ind && props.list[ind-1].pid-info.pid>1) &&
|
{!!(props.deletion_detect && props.mode==='list' && ind && props.list[ind-1].pid-info.pid>1) &&
|
||||||
<div className="flow-item-row">
|
<div className="flow-item-row">
|
||||||
<div className="box box-tip flow-item box-danger">
|
<div className="box box-tip flow-item box-danger">
|
||||||
@@ -349,6 +350,7 @@ function FlowChunk(props) {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<FlowItemRow info={info} show_sidebar={props.show_sidebar} token={token} />
|
<FlowItemRow info={info} show_sidebar={props.show_sidebar} token={token} />
|
||||||
|
</div>
|
||||||
</LazyLoad>
|
</LazyLoad>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.login-form form p {
|
.login-form p {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, {Component, PureComponent} from 'react';
|
import React, {Component, PureComponent} from 'react';
|
||||||
import {SafeTextarea} from './Common';
|
import {SafeTextarea} from './Common';
|
||||||
|
import md5 from 'md5';
|
||||||
|
|
||||||
import './UserAction.css';
|
import './UserAction.css';
|
||||||
|
|
||||||
@@ -8,6 +9,10 @@ const LOGIN_BASE=window.location.protocol==='https:' ? '/login_proxy' : 'http://
|
|||||||
const MAX_IMG_PX=2000;
|
const MAX_IMG_PX=2000;
|
||||||
const MAX_IMG_FILESIZE=256000;
|
const MAX_IMG_FILESIZE=256000;
|
||||||
|
|
||||||
|
const ISOP_APPKEY='0feb3a8a831e11e8933a0050568508a5';
|
||||||
|
const ISOP_APPCODE='0fec960a831e11e8933a0050568508a5';
|
||||||
|
const ISOP_SVCID='PERSON_BASE_INFO,STUDENT_SCORE,STUDENT_COURSE_TABLE,STUDENT_COURSE_TABLE_ROOM,CARD_BALANCE';
|
||||||
|
|
||||||
export const TokenCtx=React.createContext({
|
export const TokenCtx=React.createContext({
|
||||||
value: null,
|
value: null,
|
||||||
set_value: ()=>{},
|
set_value: ()=>{},
|
||||||
@@ -24,8 +29,25 @@ export class LoginForm extends Component {
|
|||||||
this.password_ref=React.createRef();
|
this.password_ref=React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
do_login(event,set_token) {
|
do_sendcode() {
|
||||||
event.preventDefault();
|
if(this.state.loading_status==='loading')
|
||||||
|
return;
|
||||||
|
|
||||||
|
let param=
|
||||||
|
'user='+this.username_ref.current.value+
|
||||||
|
'&svcId='+ISOP_SVCID+
|
||||||
|
'&appKey='+ISOP_APPKEY+
|
||||||
|
'×tamp='+(+new Date());
|
||||||
|
|
||||||
|
fetch(
|
||||||
|
'https://isop.pku.edu.cn/svcpub/svc/oauth/validcode?'+param+
|
||||||
|
'&msg='+md5(param+ISOP_APPCODE),
|
||||||
|
{mode: 'no-cors'}
|
||||||
|
);
|
||||||
|
alert('短信验证码应该会发到您的手机上,请注意查收!');
|
||||||
|
}
|
||||||
|
|
||||||
|
do_login(set_token) {
|
||||||
if(this.state.loading_status==='loading')
|
if(this.state.loading_status==='loading')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -33,8 +55,9 @@ export class LoginForm extends Component {
|
|||||||
loading_status: 'loading',
|
loading_status: 'loading',
|
||||||
});
|
});
|
||||||
let data=new URLSearchParams();
|
let data=new URLSearchParams();
|
||||||
data.append('uid', this.username_ref.current.value);
|
data.append('username', this.username_ref.current.value);
|
||||||
data.append('password', this.password_ref.current.value);
|
data.append('valid_code', this.password_ref.current.value);
|
||||||
|
data.append('isnewloginflow', 'true');
|
||||||
fetch(LOGIN_BASE+'/login.php?platform=hole_xmcp_ml', {
|
fetch(LOGIN_BASE+'/login.php?platform=hole_xmcp_ml', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -68,44 +91,43 @@ export class LoginForm extends Component {
|
|||||||
return (
|
return (
|
||||||
<TokenCtx.Consumer>{(token)=>
|
<TokenCtx.Consumer>{(token)=>
|
||||||
<div className="login-form box">
|
<div className="login-form box">
|
||||||
<form onSubmit={(e)=>this.do_login(e,token.set_value)}>
|
|
||||||
{token.value ?
|
{token.value ?
|
||||||
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<b>您已登录。</b>Token: <code>{token.value||'(null)'}</code> <br />
|
<b>您已登录。</b>
|
||||||
|
<button type="button" onClick={()=>{token.set_value(null);}}>注销</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Token: <code>{token.value||'(null)'}</code> <br />
|
||||||
请勿泄露 Token,它代表您的登录状态,与您的账户唯一对应且泄露后无法重置
|
请勿泄露 Token,它代表您的登录状态,与您的账户唯一对应且泄露后无法重置
|
||||||
</p> :
|
</p>
|
||||||
|
</div> :
|
||||||
<p>登录后可以使用关注、回复等功能</p>
|
<p>登录后可以使用关注、回复等功能</p>
|
||||||
}
|
}
|
||||||
<p>
|
<p>
|
||||||
<label>
|
<label>
|
||||||
学号:
|
学号
|
||||||
<input ref={this.username_ref} type="tel" />
|
<input ref={this.username_ref} type="tel" />
|
||||||
</label>
|
</label>
|
||||||
|
<button type="button" disabled={this.state.loading_status==='loading'}
|
||||||
|
onClick={(e)=>this.do_sendcode()}>
|
||||||
|
发送验证码
|
||||||
|
</button>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label>
|
<label>
|
||||||
密码:
|
验证码
|
||||||
<input ref={this.password_ref} type="password" />
|
<input ref={this.password_ref} type="tel" />
|
||||||
</label>
|
</label>
|
||||||
</p>
|
<button type="button" disabled={this.state.loading_status==='loading'}
|
||||||
<p>
|
onClick={(e)=>this.do_login(token.set_value)}>
|
||||||
{this.state.loading_status==='loading' ?
|
登录
|
||||||
<button disabled="disbled">
|
|
||||||
<span className="icon icon-loading" />
|
|
||||||
正在登录
|
|
||||||
</button> :
|
|
||||||
<button type="submit">
|
|
||||||
<span className="icon icon-login" />
|
|
||||||
登录
|
|
||||||
</button>
|
</button>
|
||||||
}
|
|
||||||
<button type="button" onClick={()=>{token.set_value(null);}}>退出</button>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
您的密码会被发送到 PKU Helper 服务器 <br />
|
登录请求会被发送到北大统一验证接口和 PKU Helper 服务器 <br />
|
||||||
我们不会记录您的密码和个人信息
|
我们不会记录或使用您的登录信息
|
||||||
</p>
|
</p>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
}</TokenCtx.Consumer>
|
}</TokenCtx.Consumer>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -137,5 +137,5 @@ export const API={
|
|||||||
}
|
}
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user