feat: authorize page

This commit is contained in:
FoskyM 2023-10-01 22:09:46 +08:00
parent 8a23f8ddf0
commit 663828aaf7
No known key found for this signature in database
GPG key ID: 42C0ED6994AD7E9C
8 changed files with 200 additions and 110 deletions

BIN
js/dist/admin.js generated vendored

Binary file not shown.

BIN
js/dist/admin.js.map generated vendored

Binary file not shown.

BIN
js/dist/forum.js generated vendored

Binary file not shown.

BIN
js/dist/forum.js.map generated vendored

Binary file not shown.

View file

@ -5,128 +5,204 @@ import IndexPage from 'flarum/forum/components/IndexPage';
import LogInModal from 'flarum/forum/components/LogInModal'; import LogInModal from 'flarum/forum/components/LogInModal';
import extractText from 'flarum/common/utils/extractText'; import extractText from 'flarum/common/utils/extractText';
import Tooltip from 'flarum/common/components/Tooltip'; import Tooltip from 'flarum/common/components/Tooltip';
import Button from 'flarum/common/components/Button';
export default class AuthorizePage extends IndexPage { export default class AuthorizePage extends IndexPage {
params = []; params = [];
client = null; client = null;
scopes = null;
client_scope = [];
loading = true;
is_authorized = false;
oninit(vnode) { oninit(vnode) {
super.oninit(vnode); super.oninit(vnode);
if (!app.session.user) { if (!app.session.user) {
setTimeout(() => app.modal.show(LogInModal), 500); setTimeout(() => app.modal.show(LogInModal), 500);
} }
const params = m.route.param(); const params = m.route.param();
if (params.client_id == null || params.response_type == null || params.redirect_uri == null) { if (params.client_id == null || params.response_type == null || params.redirect_uri == null) {
m.route.set('/'); m.route.set('/');
} else {
this.params = params;
app.store.find('oauth-clients', params.client_id).then(client => {
if (client.length === 0) {
m.route.set('/');
} else { } else {
this.params = params; this.client = client[0];
app.store.find('oauth-clients', params.client_id).then(client => { let uris = null;
if (client.length === 0) { if (this.client.redirect_uri().indexOf(' ') > -1) {
m.route.set('/'); uris = this.client.redirect_uri().split(' ');
} else { } else {
this.client = client[0]; uris = [this.client.redirect_uri()];
let uris = null; }
if (this.client.redirect_uri().indexOf(' ') > -1) {
uris = this.client.redirect_uri().split(' ');
} else {
uris = [this.client.redirect_uri()];
}
if (app.forum.attribute('foskym-oauth-center.require_exact_redirect_uri') && uris.indexOf(params.redirect_uri) == -1) { if (app.forum.attribute('foskym-oauth-center.require_exact_redirect_uri') && uris.indexOf(params.redirect_uri) == -1) {
m.route.set('/'); m.route.set('/');
} }
if (app.forum.attribute('foskym-oauth-center.allow_implicit') && params.response_type == 'token') { if (app.forum.attribute('foskym-oauth-center.allow_implicit') && params.response_type == 'token') {
m.route.set('/'); m.route.set('/');
} }
if (app.forum.attribute('foskym-oauth-center.enforce_state') && params.enforce_state == null) { if (app.forum.attribute('foskym-oauth-center.enforce_state') && params.enforce_state == null) {
m.route.set('/'); m.route.set('/');
} }
}
app.store.find('oauth-scopes').then((scopes) => {
this.scopes = scopes
let scope = params.scope;
if (params.scope == null) {
scope = this.client.scope();
}
let scopes_temp = [];
if (scope == null) {
scopes_temp = [];
} else if (scope.indexOf(' ') > -1) {
scopes_temp = scope.split(' ');
} else {
scopes_temp = [scope];
}
let default_scopes = [];
this.scopes.map(scope => {
if (scope.is_default() === 1) {
default_scopes.push(scope);
}
}); });
scopes_temp = scopes_temp.concat(default_scopes);
this.client_scope = scopes_temp.filter((scope, index) => scopes_temp.indexOf(scope) === index);
console.log( this.client_scope );
this.loading = false;
m.redraw();
});
} }
});
} }
}
setTitle() { setTitle() {
app.setTitle(extractText(app.translator.trans('foskym-oauth-center.forum.page.title.authorize'))); app.setTitle(extractText(app.translator.trans('foskym-oauth-center.forum.page.title.authorize')));
app.setTitleCount(0); app.setTitleCount(0);
}
view() {
if (!this.client) {
return '';
} }
return (
!this.loading && <div className="AuthorizePage">
<div className="container">
<div class="oauth-area">
<div class="oauth-main">
<div class="oauth-box oauth-header">
<h2>{app.forum.attribute('title')}</h2>
<p>
{app.translator.trans('foskym-oauth-center.forum.authorize.access')} <a
href={this.client.client_home()} target="_blank">{this.client.client_name()}</a>
</p>
view() { </div>
if (!this.client) { <div class="oauth-box oauth-body">
return '';
}
return (
<div className="AuthorizePage">
<div className="container">
<div class="oauth-area">
<div class="oauth-main">
<div class="oauth-box oauth-header">
<h2>{app.forum.attribute('title')}</h2>
<p>
{app.translator.trans('foskym-oauth-center.forum.authorize.access')} <a href={this.client.client_home()} target="_blank">{this.client.client_name()}</a>
</p>
</div> <div class="oauth-top">
<div class="oauth-box oauth-body"> <img src={app.forum.attribute('faviconUrl')}/>
<i class="fas fa-exchange-alt fa-2x"></i>
<div class="oauth-top"> <Tooltip text={this.client.client_desc()}>
<img src={app.forum.attribute('faviconUrl')}/> <img src={this.client.client_icon()}/>
<i class="fas fa-exchange-alt fa-2x"></i> </Tooltip>
<Tooltip text={this.client.client_desc()}>
<img src={this.client.client_icon()}/>
</Tooltip>
</div>
<div class="oauth-scope-area">
<div class="oauth-scope">
<div class="oauth-scope-left">
<img class="oauth-scope-object" src="/static/icon.jpg" style="width:32px"/>
</div>
<div class="oauth-scope-body">
<h6 class="oauth-scope-heading">
保持对已向 计量便民平台 授予访问权限的数据的访问权限 </h6>
<small>
即使当前没有使用该应用也允许 计量便民平台 查看和更新你授予其访问权限的数据这不会向
计量便民平台 授予任何其他权限 </small>
</div>
</div>
<div class="oauth-scope">
<div class="oauth-scope-left">
<i class="oauth-scope-object fa-2x fa fa-user"
style="margin-left:2px;color:#000"></i>
</div>
<div class="oauth-scope-body">
<h6 class="oauth-scope-heading">
读取用户个人资料 </h6>
<small>
访问该用户(mouse123)的个人信息最新动态等 </small>
</div>
</div>
</div>
<form class="oauth-form" method="post" id="form">
<input type="hidden" name="response_type" value="code"/>
<input type="hidden" name="client_id" value="0eaCTcndUqIGo9LymQ3YVZGYVpEXcHer"/>
<input type="hidden" name="redirect_uri"
value="http://cjludev.top/user/auth/callback"/>
<input type="hidden" name="state" value="123"/>
<input type="hidden" name="scope" value="basic get_user_info"/>
<div style="display: flex;">
<button class="btn btn-success btn-block" type="submit"
id="authorize" style="width: 50%;">授权
</button>
<button class="btn btn-danger btn-block" id="refuse"
style="width: 50%;">拒绝
</button>
</div>
</form>
</div>
</div>
</div>
</div> </div>
<div class="oauth-scope-area">
{
this.client_scope.length > 0 && this.client_scope.map(scope => {
let scope_info = null;
this.scopes.map(s => {
if (s.scope() === scope.scope()) {
scope_info = s;
}
});
if (scope_info == null) {
return '';
}
return (
<div class="oauth-scope">
<div class="oauth-scope-left">
{
(scope_info.scope_icon().indexOf('fa-') > -1) ?
<i class={"oauth-scope-object fa-2x " + scope_info.scope_icon()}
style="margin-left:2px;color:#000"></i> :
<img class="oauth-scope-object" src={scope_info.scope_icon()} style="width:32px"/>
}
</div>
<div class="oauth-scope-body">
<h6 class="oauth-scope-heading">
{scope_info.scope_name()}
</h6>
<small>
{
scope_info.scope_desc()
.replace('{client_name}', this.client.client_name())
.replace('{user}', app.session.user.attribute('displayName'))
}
</small>
</div>
</div>
);
})
}
</div>
<form class="oauth-form" method="post" id="form" onsubmit={this.onsubmit.bind(this)}>
{/* <input type="hidden" name="response_type" value={this.params.response_type}/>
<input type="hidden" name="client_id" value={this.params.client_id}/>
<input type="hidden" name="redirect_uri"
value={this.params.redirect_uri}/>
<input type="hidden" name="state" value={this.params.state}/>
<input type="hidden" name="scope" value={this.params.scope}/>*/}
<input type="hidden" name="is_authorized" value={this.is_authorized}/>
<div style="display: flex; margin-top: 15px" class="oauth-form-item">
<Button className="Button" type="submit" style="width: 50%;" onclick={
this.is_authorized = false
}>
{app.translator.trans('foskym-oauth-center.forum.authorize.deny')}
</Button>
<Button className="Button Button--primary" type="submit" style="width: 50%;" onclick={
this.is_authorized = true
}>
{app.translator.trans('foskym-oauth-center.forum.authorize.agree')}
</Button>
</div>
</form>
</div>
</div> </div>
); </div>
} </div>
</div>
);
}
onsubmit(e) {
e.preventDefault();
app.request({
method: 'POST',
url: '/oauth/authorize',
body: {
response_type: this.params.response_type,
client_id: this.params.client_id,
redirect_uri: this.params.redirect_uri,
state: this.params.state,
scope: this.params.scope,
is_authorized: this.is_authorized,
}
}).then((r) => console.log(r));
// Some form handling logic here
}
} }

View file

@ -42,6 +42,10 @@
} }
} }
.Checkbox {
padding: 0 10px;
}
.FormControl { .FormControl {
background: @body-bg; background: @body-bg;
border-color: @control-bg; border-color: @control-bg;

View file

@ -13,6 +13,8 @@
width: 376px; width: 376px;
margin: 0 auto; margin: 0 auto;
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0px 0px 15px 0px #bdbdbd;
border-radius: 12px;
} }
.oauth-main::before { .oauth-main::before {
@ -23,8 +25,8 @@
height: 100%; height: 100%;
left: 0; left: 0;
top: 0; top: 0;
box-shadow: 0 25px 50px #00000030;
background: hsla(0, 0%, 100%, .3); background: hsla(0, 0%, 100%, .3);
border-radius: 12px;
} }
.oauth-box { .oauth-box {
@ -36,6 +38,7 @@
backdrop-filter: blur(0); backdrop-filter: blur(0);
text-align: center; text-align: center;
box-shadow: 0 5px 10px -5px #d2d2d2; box-shadow: 0 5px 10px -5px #d2d2d2;
border-radius: 12px 12px 0 0;
} }
.oauth-header h2 { .oauth-header h2 {
@ -51,6 +54,10 @@
color: #333; color: #333;
} }
.oauth-body {
border-radius: 0 0 12px 12px;
}
.oauth-body .oauth-form-item { .oauth-body .oauth-form-item {
position: relative; position: relative;
margin-bottom: 15px; margin-bottom: 15px;
@ -100,7 +107,7 @@ label:before {
} }
.oauth-header { .oauth-header {
background-color: #fff; // background-color: #fff;
} }
body { body {
@ -209,6 +216,7 @@ img.oauth-scope-object {
margin-top: 0; margin-top: 0;
font-weight: 800; font-weight: 800;
color: #382e2e; color: #382e2e;
margin-block-end: 0;
} }
.oauth-scope-body small { .oauth-scope-body small {

View file

@ -38,3 +38,5 @@ foskym-oauth-center:
authorized: 授权记录 authorized: 授权记录
authorize: authorize:
access: 授权访问 access: 授权访问
agree: 授权
deny: 拒绝