gitea支持启动时指定clientId和接口地址等

This commit is contained in:
xiaoqi.cxq 2022-10-02 00:20:01 +08:00
parent 95d27a4a0a
commit 21a3e59b5d
7 changed files with 142 additions and 38 deletions

View File

@ -15,6 +15,9 @@ wordpressSecret: ""
paypalReceiverEmail: ""
awsAccessKeyId: ""
awsSecretAccessKey: ""
giteaClientId: ""
giteaClientSecret: ""
giteaUrl: ""
replicaCount: 1

View File

@ -9,4 +9,7 @@ module.exports = merge(prodEnv, {
GITEE_CLIENT_ID: '"925ba7c78b85dec984f7877e4aca5cab10ae333c6d68e761bdb0b9dfb8f55672"',
GITEE_CLIENT_SECRET: '"f05731066e42d307339dc8ebbb037a103881dafc7207a359a393b87749f1c562"',
CLIENT_ID: '"thF3qCGLN39OtafjGnqHyj6n02WwE6xD"',
// GITEA_CLIENT_ID: '"fe30f8f9-b1e8-4531-8f72-c1a5d3912805"',
// GITEA_CLIENT_SECRET: '"lus7oMnb3H6M1hsChndphArE20Txr7erwJLf7SDBQWTw"',
// GITEA_URL: '"https://gitea.test.com"',
})

View File

@ -13,6 +13,9 @@ const giteeClientSecret = process.env.GITEE_CLIENT_SECRET;
const googleClientId = process.env.GOOGLE_CLIENT_ID;
const googleApiKey = process.env.GOOGLE_API_KEY;
const wordpressClientId = process.env.WORDPRESS_CLIENT_ID;
const giteaClientId = process.env.GITEA_CLIENT_ID;
const giteaClientSecret = process.env.GITEA_CLIENT_SECRET;
const giteaUrl = process.env.GITEA_URL;
exports.values = {
pandocPath,
@ -29,6 +32,9 @@ exports.values = {
googleClientId,
googleApiKey,
wordpressClientId,
giteaClientId,
giteaClientSecret,
giteaUrl,
};
exports.publicValues = {
@ -39,4 +45,6 @@ exports.publicValues = {
googleApiKey,
wordpressClientId,
allowSponsorship: !!paypalReceiverEmail,
giteaClientId,
giteaUrl,
};

41
server/gitea.js Normal file
View File

@ -0,0 +1,41 @@
const qs = require('qs');
const request = require('request');
const conf = require('./conf');
function giteaToken(queryParam) {
return new Promise((resolve, reject) => {
request({
method: 'POST',
url: `${conf.values.giteaUrl}/login/oauth/access_token`,
headers: {
'content-type': 'application/json',
},
json: true,
body: {
...queryParam,
client_id: conf.values.giteaClientId,
client_secret: conf.values.giteaClientSecret,
},
}, (err, res, body) => {
if (err) {
reject(err);
}
const token = body.access_token;
if (token) {
resolve(body);
} else {
reject(res.statusCode + ',body:' + JSON.stringify(body));
}
});
});
}
exports.giteaToken = (req, res) => {
giteaToken(req.query)
.then(
tokenBody => res.send(tokenBody),
err => res
.status(400)
.send(err ? err.message || err.toString() : 'bad_code'),
);
};

View File

@ -5,6 +5,7 @@ const path = require('path');
const user = require('./user');
const github = require('./github');
const gitee = require('./gitee');
const gitea = require('./gitea');
const pdf = require('./pdf');
const pandoc = require('./pandoc');
const conf = require('./conf');
@ -27,6 +28,7 @@ module.exports = (app) => {
app.get('/oauth2/githubToken', github.githubToken);
app.get('/oauth2/giteeToken', gitee.giteeToken);
app.get('/oauth2/giteaToken', gitea.giteaToken);
app.get('/conf', (req, res) => res.send(conf.publicValues));
app.get('/userInfo', user.userInfo);
app.post('/pdfExport', pdf.generate);

View File

@ -5,28 +5,30 @@
<icon-provider provider-id="gitea"></icon-provider>
</div>
<p>将您的<b>Gitea</b>链接到<b>StackEdit中文版</b></p>
<form-entry label="Gitea URL" error="serverUrl">
<input v-if="config.forceServerUrl" slot="field" class="textfield" type="text" disabled="disabled" v-model="config.forceServerUrl">
<input v-else slot="field" class="textfield" type="text" v-model.trim="serverUrl" @keydown.enter="resolve()">
<div class="form-entry__info">
<b>例如:</b> https://gitea.example.com/
<span v-if="httpAppUrl">
非https的URL请跳转到 <a :href="httpAppUrl" target="_blank">HTTP链接</a> 添加Gitea
</span>
</div>
</form-entry>
<form-entry label="Application ID" error="applicationId">
<input slot="field" class="textfield" type="text" v-model.trim="applicationId" @keydown.enter="resolve()">
</form-entry>
<form-entry label="Application Secret" error="applicationSecret">
<input slot="field" class="textfield" type="text" v-model.trim="applicationSecret" @keydown.enter="resolve()">
<div class="form-entry__info">
您必须使用重定向url <b>{{redirectUrl}}</b>配置OAuth2应用程序
</div>
<div class="form-entry__actions">
<a href="https://docs.gitea.io/en-us/oauth2-provider/" target="_blank">更多信息</a>
</div>
</form-entry>
<template v-if="!useServerConf">
<form-entry label="Gitea URL" error="serverUrl">
<input v-if="config.forceServerUrl" slot="field" class="textfield" type="text" disabled="disabled" v-model="config.forceServerUrl">
<input v-else slot="field" class="textfield" type="text" v-model.trim="serverUrl" @keydown.enter="resolve()">
<div class="form-entry__info">
<b>例如:</b> https://gitea.example.com/
<span v-if="httpAppUrl">
非https的URL请跳转到 <a :href="httpAppUrl" target="_blank">HTTP链接</a> 添加Gitea
</span>
</div>
</form-entry>
<form-entry label="Application ID" error="applicationId">
<input slot="field" class="textfield" type="text" v-model.trim="applicationId" @keydown.enter="resolve()">
</form-entry>
<form-entry label="Application Secret" error="applicationSecret">
<input slot="field" class="textfield" type="text" v-model.trim="applicationSecret" @keydown.enter="resolve()">
<div class="form-entry__info">
您必须使用重定向url <b>{{redirectUrl}}</b>配置OAuth2应用程序
</div>
<div class="form-entry__actions">
<a href="https://docs.gitea.io/en-us/oauth2-provider/" target="_blank">更多信息</a>
</div>
</form-entry>
</template>
</div>
<div class="modal__button-bar">
<button class="button" @click="config.reject()">取消</button>
@ -38,6 +40,7 @@
<script>
import modalTemplate from '../common/modalTemplate';
import constants from '../../../data/constants';
import store from '../../../store';
export default modalTemplate({
data: () => ({
@ -55,9 +58,19 @@ export default modalTemplate({
}
return null;
},
// 使
useServerConf() {
const confClientId = store.getters['data/serverConf'].giteaClientId;
const confServerUrl = store.getters['data/serverConf'].giteaUrl;
return !!confClientId && !!confServerUrl;
},
},
methods: {
resolve() {
if (this.useServerConf) {
this.config.resolve({});
return;
}
const serverUrl = this.config.forceServerUrl || this.serverUrl;
if (!serverUrl) {
this.setError('serverUrl');

View File

@ -57,27 +57,61 @@ export default {
serverUrl, applicationId, applicationSecret,
sub = null, silent = false, refreshToken,
) {
let apiUrl = serverUrl;
let clientId = applicationId;
let useServerConf = false;
// 获取gitea配置的参数
const confClientId = store.getters['data/serverConf'].giteaClientId;
const confServerUrl = store.getters['data/serverConf'].giteaUrl;
// 存在gitea配置则使用后端配置
if (confClientId && confServerUrl) {
apiUrl = confServerUrl;
clientId = confClientId;
useServerConf = true;
}
let tokenBody;
if (!silent) {
// Get an OAuth2 code
const { code } = await networkSvc.startOauth2(
`${serverUrl}/login/oauth/authorize`,
`${apiUrl}/login/oauth/authorize`,
{
client_id: applicationId,
client_id: clientId,
response_type: 'code',
redirect_uri: constants.oauth2RedirectUri,
},
silent,
);
// Exchange code with token
if (useServerConf) {
tokenBody = (await networkSvc.request({
method: 'GET',
url: 'oauth2/giteaToken',
params: {
code,
grant_type: 'authorization_code',
redirect_uri: constants.oauth2RedirectUri,
},
})).body;
} else {
// Exchange code with token
tokenBody = (await networkSvc.request({
method: 'POST',
url: `${apiUrl}/login/oauth/access_token`,
body: {
client_id: clientId,
client_secret: applicationSecret,
code,
grant_type: 'authorization_code',
redirect_uri: constants.oauth2RedirectUri,
},
})).body;
}
} else if (useServerConf) {
tokenBody = (await networkSvc.request({
method: 'POST',
url: `${serverUrl}/login/oauth/access_token`,
body: {
client_id: applicationId,
client_secret: applicationSecret,
code,
grant_type: 'authorization_code',
method: 'GET',
url: 'oauth2/giteaToken',
params: {
refresh_token: refreshToken,
grant_type: 'refresh_token',
redirect_uri: constants.oauth2RedirectUri,
},
})).body;
@ -85,9 +119,9 @@ export default {
// Exchange refreshToken with token
tokenBody = (await networkSvc.request({
method: 'POST',
url: `${serverUrl}/login/oauth/access_token`,
url: `${apiUrl}/login/oauth/access_token`,
body: {
client_id: applicationId,
client_id: clientId,
client_secret: applicationSecret,
refresh_token: refreshToken,
grant_type: 'refresh_token',
@ -99,10 +133,10 @@ export default {
const accessToken = tokenBody.access_token;
// Call the user info endpoint
const user = await request({ accessToken, serverUrl }, {
const user = await request({ accessToken, serverUrl: apiUrl }, {
url: 'user',
});
const uniqueSub = `${serverUrl}/${user.username}`;
const uniqueSub = `${apiUrl}/${user.username}`;
userSvc.addUserInfo({
id: `${subPrefix}:${uniqueSub}`,
name: user.username,
@ -119,12 +153,12 @@ export default {
const token = {
accessToken,
name: user.username,
applicationId,
applicationId: clientId,
applicationSecret,
imgStorages: oldToken && oldToken.imgStorages,
refreshToken: tokenBody.refresh_token,
expiresOn: Date.now() + (tokenBody.expires_in * 1000),
serverUrl,
serverUrl: apiUrl,
sub: uniqueSub,
};