gitea支持启动时指定clientId和接口地址等
This commit is contained in:
parent
95d27a4a0a
commit
21a3e59b5d
@ -15,6 +15,9 @@ wordpressSecret: ""
|
|||||||
paypalReceiverEmail: ""
|
paypalReceiverEmail: ""
|
||||||
awsAccessKeyId: ""
|
awsAccessKeyId: ""
|
||||||
awsSecretAccessKey: ""
|
awsSecretAccessKey: ""
|
||||||
|
giteaClientId: ""
|
||||||
|
giteaClientSecret: ""
|
||||||
|
giteaUrl: ""
|
||||||
|
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
|
|
||||||
|
@ -9,4 +9,7 @@ module.exports = merge(prodEnv, {
|
|||||||
GITEE_CLIENT_ID: '"925ba7c78b85dec984f7877e4aca5cab10ae333c6d68e761bdb0b9dfb8f55672"',
|
GITEE_CLIENT_ID: '"925ba7c78b85dec984f7877e4aca5cab10ae333c6d68e761bdb0b9dfb8f55672"',
|
||||||
GITEE_CLIENT_SECRET: '"f05731066e42d307339dc8ebbb037a103881dafc7207a359a393b87749f1c562"',
|
GITEE_CLIENT_SECRET: '"f05731066e42d307339dc8ebbb037a103881dafc7207a359a393b87749f1c562"',
|
||||||
CLIENT_ID: '"thF3qCGLN39OtafjGnqHyj6n02WwE6xD"',
|
CLIENT_ID: '"thF3qCGLN39OtafjGnqHyj6n02WwE6xD"',
|
||||||
|
// GITEA_CLIENT_ID: '"fe30f8f9-b1e8-4531-8f72-c1a5d3912805"',
|
||||||
|
// GITEA_CLIENT_SECRET: '"lus7oMnb3H6M1hsChndphArE20Txr7erwJLf7SDBQWTw"',
|
||||||
|
// GITEA_URL: '"https://gitea.test.com"',
|
||||||
})
|
})
|
@ -13,6 +13,9 @@ const giteeClientSecret = process.env.GITEE_CLIENT_SECRET;
|
|||||||
const googleClientId = process.env.GOOGLE_CLIENT_ID;
|
const googleClientId = process.env.GOOGLE_CLIENT_ID;
|
||||||
const googleApiKey = process.env.GOOGLE_API_KEY;
|
const googleApiKey = process.env.GOOGLE_API_KEY;
|
||||||
const wordpressClientId = process.env.WORDPRESS_CLIENT_ID;
|
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 = {
|
exports.values = {
|
||||||
pandocPath,
|
pandocPath,
|
||||||
@ -29,6 +32,9 @@ exports.values = {
|
|||||||
googleClientId,
|
googleClientId,
|
||||||
googleApiKey,
|
googleApiKey,
|
||||||
wordpressClientId,
|
wordpressClientId,
|
||||||
|
giteaClientId,
|
||||||
|
giteaClientSecret,
|
||||||
|
giteaUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.publicValues = {
|
exports.publicValues = {
|
||||||
@ -39,4 +45,6 @@ exports.publicValues = {
|
|||||||
googleApiKey,
|
googleApiKey,
|
||||||
wordpressClientId,
|
wordpressClientId,
|
||||||
allowSponsorship: !!paypalReceiverEmail,
|
allowSponsorship: !!paypalReceiverEmail,
|
||||||
|
giteaClientId,
|
||||||
|
giteaUrl,
|
||||||
};
|
};
|
||||||
|
41
server/gitea.js
Normal file
41
server/gitea.js
Normal 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'),
|
||||||
|
);
|
||||||
|
};
|
@ -5,6 +5,7 @@ const path = require('path');
|
|||||||
const user = require('./user');
|
const user = require('./user');
|
||||||
const github = require('./github');
|
const github = require('./github');
|
||||||
const gitee = require('./gitee');
|
const gitee = require('./gitee');
|
||||||
|
const gitea = require('./gitea');
|
||||||
const pdf = require('./pdf');
|
const pdf = require('./pdf');
|
||||||
const pandoc = require('./pandoc');
|
const pandoc = require('./pandoc');
|
||||||
const conf = require('./conf');
|
const conf = require('./conf');
|
||||||
@ -27,6 +28,7 @@ module.exports = (app) => {
|
|||||||
|
|
||||||
app.get('/oauth2/githubToken', github.githubToken);
|
app.get('/oauth2/githubToken', github.githubToken);
|
||||||
app.get('/oauth2/giteeToken', gitee.giteeToken);
|
app.get('/oauth2/giteeToken', gitee.giteeToken);
|
||||||
|
app.get('/oauth2/giteaToken', gitea.giteaToken);
|
||||||
app.get('/conf', (req, res) => res.send(conf.publicValues));
|
app.get('/conf', (req, res) => res.send(conf.publicValues));
|
||||||
app.get('/userInfo', user.userInfo);
|
app.get('/userInfo', user.userInfo);
|
||||||
app.post('/pdfExport', pdf.generate);
|
app.post('/pdfExport', pdf.generate);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<icon-provider provider-id="gitea"></icon-provider>
|
<icon-provider provider-id="gitea"></icon-provider>
|
||||||
</div>
|
</div>
|
||||||
<p>将您的<b>Gitea</b>链接到<b>StackEdit中文版</b>。</p>
|
<p>将您的<b>Gitea</b>链接到<b>StackEdit中文版</b>。</p>
|
||||||
|
<template v-if="!useServerConf">
|
||||||
<form-entry label="Gitea URL" error="serverUrl">
|
<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-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()">
|
<input v-else slot="field" class="textfield" type="text" v-model.trim="serverUrl" @keydown.enter="resolve()">
|
||||||
@ -27,6 +28,7 @@
|
|||||||
<a href="https://docs.gitea.io/en-us/oauth2-provider/" target="_blank">更多信息</a>
|
<a href="https://docs.gitea.io/en-us/oauth2-provider/" target="_blank">更多信息</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal__button-bar">
|
<div class="modal__button-bar">
|
||||||
<button class="button" @click="config.reject()">取消</button>
|
<button class="button" @click="config.reject()">取消</button>
|
||||||
@ -38,6 +40,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import modalTemplate from '../common/modalTemplate';
|
import modalTemplate from '../common/modalTemplate';
|
||||||
import constants from '../../../data/constants';
|
import constants from '../../../data/constants';
|
||||||
|
import store from '../../../store';
|
||||||
|
|
||||||
export default modalTemplate({
|
export default modalTemplate({
|
||||||
data: () => ({
|
data: () => ({
|
||||||
@ -55,9 +58,19 @@ export default modalTemplate({
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
// 是否使用服务端配置
|
||||||
|
useServerConf() {
|
||||||
|
const confClientId = store.getters['data/serverConf'].giteaClientId;
|
||||||
|
const confServerUrl = store.getters['data/serverConf'].giteaUrl;
|
||||||
|
return !!confClientId && !!confServerUrl;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resolve() {
|
resolve() {
|
||||||
|
if (this.useServerConf) {
|
||||||
|
this.config.resolve({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
const serverUrl = this.config.forceServerUrl || this.serverUrl;
|
const serverUrl = this.config.forceServerUrl || this.serverUrl;
|
||||||
if (!serverUrl) {
|
if (!serverUrl) {
|
||||||
this.setError('serverUrl');
|
this.setError('serverUrl');
|
||||||
|
@ -57,37 +57,71 @@ export default {
|
|||||||
serverUrl, applicationId, applicationSecret,
|
serverUrl, applicationId, applicationSecret,
|
||||||
sub = null, silent = false, refreshToken,
|
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;
|
let tokenBody;
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
// Get an OAuth2 code
|
// Get an OAuth2 code
|
||||||
const { code } = await networkSvc.startOauth2(
|
const { code } = await networkSvc.startOauth2(
|
||||||
`${serverUrl}/login/oauth/authorize`,
|
`${apiUrl}/login/oauth/authorize`,
|
||||||
{
|
{
|
||||||
client_id: applicationId,
|
client_id: clientId,
|
||||||
response_type: 'code',
|
response_type: 'code',
|
||||||
redirect_uri: constants.oauth2RedirectUri,
|
redirect_uri: constants.oauth2RedirectUri,
|
||||||
},
|
},
|
||||||
silent,
|
silent,
|
||||||
);
|
);
|
||||||
|
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
|
// Exchange code with token
|
||||||
tokenBody = (await networkSvc.request({
|
tokenBody = (await networkSvc.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${serverUrl}/login/oauth/access_token`,
|
url: `${apiUrl}/login/oauth/access_token`,
|
||||||
body: {
|
body: {
|
||||||
client_id: applicationId,
|
client_id: clientId,
|
||||||
client_secret: applicationSecret,
|
client_secret: applicationSecret,
|
||||||
code,
|
code,
|
||||||
grant_type: 'authorization_code',
|
grant_type: 'authorization_code',
|
||||||
redirect_uri: constants.oauth2RedirectUri,
|
redirect_uri: constants.oauth2RedirectUri,
|
||||||
},
|
},
|
||||||
})).body;
|
})).body;
|
||||||
|
}
|
||||||
|
} else if (useServerConf) {
|
||||||
|
tokenBody = (await networkSvc.request({
|
||||||
|
method: 'GET',
|
||||||
|
url: 'oauth2/giteaToken',
|
||||||
|
params: {
|
||||||
|
refresh_token: refreshToken,
|
||||||
|
grant_type: 'refresh_token',
|
||||||
|
redirect_uri: constants.oauth2RedirectUri,
|
||||||
|
},
|
||||||
|
})).body;
|
||||||
} else {
|
} else {
|
||||||
// Exchange refreshToken with token
|
// Exchange refreshToken with token
|
||||||
tokenBody = (await networkSvc.request({
|
tokenBody = (await networkSvc.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `${serverUrl}/login/oauth/access_token`,
|
url: `${apiUrl}/login/oauth/access_token`,
|
||||||
body: {
|
body: {
|
||||||
client_id: applicationId,
|
client_id: clientId,
|
||||||
client_secret: applicationSecret,
|
client_secret: applicationSecret,
|
||||||
refresh_token: refreshToken,
|
refresh_token: refreshToken,
|
||||||
grant_type: 'refresh_token',
|
grant_type: 'refresh_token',
|
||||||
@ -99,10 +133,10 @@ export default {
|
|||||||
const accessToken = tokenBody.access_token;
|
const accessToken = tokenBody.access_token;
|
||||||
|
|
||||||
// Call the user info endpoint
|
// Call the user info endpoint
|
||||||
const user = await request({ accessToken, serverUrl }, {
|
const user = await request({ accessToken, serverUrl: apiUrl }, {
|
||||||
url: 'user',
|
url: 'user',
|
||||||
});
|
});
|
||||||
const uniqueSub = `${serverUrl}/${user.username}`;
|
const uniqueSub = `${apiUrl}/${user.username}`;
|
||||||
userSvc.addUserInfo({
|
userSvc.addUserInfo({
|
||||||
id: `${subPrefix}:${uniqueSub}`,
|
id: `${subPrefix}:${uniqueSub}`,
|
||||||
name: user.username,
|
name: user.username,
|
||||||
@ -119,12 +153,12 @@ export default {
|
|||||||
const token = {
|
const token = {
|
||||||
accessToken,
|
accessToken,
|
||||||
name: user.username,
|
name: user.username,
|
||||||
applicationId,
|
applicationId: clientId,
|
||||||
applicationSecret,
|
applicationSecret,
|
||||||
imgStorages: oldToken && oldToken.imgStorages,
|
imgStorages: oldToken && oldToken.imgStorages,
|
||||||
refreshToken: tokenBody.refresh_token,
|
refreshToken: tokenBody.refresh_token,
|
||||||
expiresOn: Date.now() + (tokenBody.expires_in * 1000),
|
expiresOn: Date.now() + (tokenBody.expires_in * 1000),
|
||||||
serverUrl,
|
serverUrl: apiUrl,
|
||||||
sub: uniqueSub,
|
sub: uniqueSub,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user