diff --git a/config/dev.env.js b/config/dev.env.js
index 0620891b..f31dba18 100644
--- a/config/dev.env.js
+++ b/config/dev.env.js
@@ -8,5 +8,5 @@ module.exports = merge(prodEnv, {
GITHUB_CLIENT_SECRET: '"80df676597abded1450926861965cc3f9bead6a0"',
GITEE_CLIENT_ID: '"925ba7c78b85dec984f7877e4aca5cab10ae333c6d68e761bdb0b9dfb8f55672"',
GITEE_CLIENT_SECRET: '"f05731066e42d307339dc8ebbb037a103881dafc7207a359a393b87749f1c562"',
- GITEE_CALLBACK: '"http://test.local.com/oauth2/callback"'
+ CLIENT_ID: '"thF3qCGLN39OtafjGnqHyj6n02WwE6xD"',
})
\ No newline at end of file
diff --git a/server/conf.js b/server/conf.js
index e71d6dd8..9b2d550b 100644
--- a/server/conf.js
+++ b/server/conf.js
@@ -10,7 +10,6 @@ const githubClientId = process.env.GITHUB_CLIENT_ID;
const githubClientSecret = process.env.GITHUB_CLIENT_SECRET;
const giteeClientId = process.env.GITEE_CLIENT_ID;
const giteeClientSecret = process.env.GITEE_CLIENT_SECRET;
-const giteeCallback = process.env.GITEE_CALLBACK;
const googleClientId = process.env.GOOGLE_CLIENT_ID;
const googleApiKey = process.env.GOOGLE_API_KEY;
const wordpressClientId = process.env.WORDPRESS_CLIENT_ID;
@@ -27,7 +26,6 @@ exports.values = {
githubClientSecret,
giteeClientId,
giteeClientSecret,
- giteeCallback,
googleClientId,
googleApiKey,
wordpressClientId,
diff --git a/src/components/menus/HistoryMenu.vue b/src/components/menus/HistoryMenu.vue
index 3389cffc..c8c9f63f 100644
--- a/src/components/menus/HistoryMenu.vue
+++ b/src/components/menus/HistoryMenu.vue
@@ -9,17 +9,17 @@
同步 {{currentFileName}} 以启用修订历史 或者 登录 Google 以同步您的主工作区。
- Loading history…
- {{currentFileName}} has no history.
+ 历史版本加载中…
+ {{currentFileName}} 没有历史版本.
@@ -39,7 +39,7 @@
-
+
diff --git a/src/data/welcomeFile.md b/src/data/welcomeFile.md
index 972fc39b..1bb5c10e 100644
--- a/src/data/welcomeFile.md
+++ b/src/data/welcomeFile.md
@@ -15,7 +15,7 @@ StackEdit 将您的文件存储在您的浏览器中,这意味着您的所有
您的所有文件和文件夹在文件资源管理器中都显示为树。您可以通过单击树中的文件从一个文件切换到另一个文件。
-##重命名文件
+## 重命名文件
您可以通过单击导航栏中的文件名或单击文件资源管理器中的**重命名**按钮来重命名当前文件。
diff --git a/src/services/providers/giteaProvider.js b/src/services/providers/giteaProvider.js
index bb77496f..df88d84c 100644
--- a/src/services/providers/giteaProvider.js
+++ b/src/services/providers/giteaProvider.js
@@ -135,17 +135,24 @@ export default new Provider({
token,
});
- return entries.map((entry) => {
- const email = entry.author_email || entry.committer_email;
- const sub = `${giteaHelper.subPrefix}:${token.serverUrl}/${email}`;
- userSvc.addUserInfo({
- id: sub,
- name: entry.author_name || entry.committer_name,
- imageUrl: '',
- });
- const date = entry.authored_date || entry.committed_date || 1;
+ return entries.map(({
+ author,
+ committer,
+ commit,
+ sha,
+ }) => {
+ let user;
+ if (author && author.login) {
+ user = author;
+ } else if (committer && committer.login) {
+ user = committer;
+ }
+ const sub = `${giteaHelper.subPrefix}:${user.login}`;
+ userSvc.addUserInfo({ id: sub, name: user.login, imageUrl: user.avatar_url });
+ const date = (commit.author && commit.author.date)
+ || (commit.committer && commit.committer.date);
return {
- id: entry.id,
+ id: sha,
sub,
created: date ? new Date(date).getTime() : 1,
};
diff --git a/src/services/providers/giteaWorkspaceProvider.js b/src/services/providers/giteaWorkspaceProvider.js
index 0ae8d0d5..fc1cd52a 100644
--- a/src/services/providers/giteaWorkspaceProvider.js
+++ b/src/services/providers/giteaWorkspaceProvider.js
@@ -251,19 +251,27 @@ export default new Provider({
path: getAbsolutePath({ id: fileSyncDataId }),
});
- return entries.map((entry) => {
- const email = entry.author_email || entry.committer_email;
- const sub = `${giteaHelper.subPrefix}:${token.serverUrl}/${email}`;
- userSvc.addUserInfo({
- id: sub,
- name: entry.author_name || entry.committer_name,
- imageUrl: '', // No way to get user's avatar url...
- });
- const date = entry.authored_date || entry.committed_date || 1;
+ return entries.map(({
+ author,
+ committer,
+ commit,
+ sha,
+ }) => {
+ let user;
+ if (author && author.login) {
+ user = author;
+ } else if (committer && committer.login) {
+ user = committer;
+ }
+ const sub = `${giteaHelper.subPrefix}:${user.login}`;
+ userSvc.addUserInfo({ id: sub, name: user.login, imageUrl: user.avatar_url });
+ const date = (commit.author && commit.author.date)
+ || (commit.committer && commit.committer.date)
+ || 1;
return {
- id: entry.id,
+ id: sha,
sub,
- created: date ? new Date(date).getTime() : 1,
+ created: new Date(date).getTime(),
};
});
},
diff --git a/src/services/providers/giteeProvider.js b/src/services/providers/giteeProvider.js
index 9c68dacd..0e719d47 100644
--- a/src/services/providers/giteeProvider.js
+++ b/src/services/providers/giteeProvider.js
@@ -135,6 +135,9 @@ export default new Provider({
user = committer;
}
const sub = `${giteeHelper.subPrefix}:${user.login}`;
+ if (user.avatar_url && user.avatar_url.endsWith('.png')) {
+ user.avatar_url = `${user.avatar_url}!avatar60`;
+ }
userSvc.addUserInfo({ id: sub, name: user.login, imageUrl: user.avatar_url });
const date = (commit.author && commit.author.date)
|| (commit.committer && commit.committer.date);
diff --git a/src/services/providers/giteeWorkspaceProvider.js b/src/services/providers/giteeWorkspaceProvider.js
index 3d5ec740..4617d3a5 100644
--- a/src/services/providers/giteeWorkspaceProvider.js
+++ b/src/services/providers/giteeWorkspaceProvider.js
@@ -249,6 +249,9 @@ export default new Provider({
user = committer;
}
const sub = `${giteeHelper.subPrefix}:${user.login}`;
+ if (user.avatar_url && user.avatar_url.endsWith('.png')) {
+ user.avatar_url = `${user.avatar_url}!avatar60`;
+ }
userSvc.addUserInfo({ id: sub, name: user.login, imageUrl: user.avatar_url });
const date = (commit.author && commit.author.date)
|| (commit.committer && commit.committer.date)
diff --git a/src/services/providers/helpers/giteaHelper.js b/src/services/providers/helpers/giteaHelper.js
index 62d5268d..53fc8618 100644
--- a/src/services/providers/helpers/giteaHelper.js
+++ b/src/services/providers/helpers/giteaHelper.js
@@ -5,6 +5,8 @@ import userSvc from '../../userSvc';
import badgeSvc from '../../badgeSvc';
import constants from '../../../data/constants';
+const tokenExpirationMargin = 5 * 60 * 1000;
+
const request = ({ accessToken, serverUrl }, options) => networkSvc.request({
...options,
url: `${serverUrl}/api/v1/${options.url}`,
@@ -51,30 +53,50 @@ export default {
/**
* https://docs.gitea.io/en-us/oauth2-provider/
*/
- async startOauth2(serverUrl, applicationId, applicationSecret, sub = null, silent = false) {
- // Get an OAuth2 code
- const { code } = await networkSvc.startOauth2(
- `${serverUrl}/login/oauth/authorize`,
- {
- client_id: applicationId,
- response_type: 'code',
- redirect_uri: constants.oauth2RedirectUri,
- },
- silent,
- );
+ async startOauth2(
+ serverUrl, applicationId, applicationSecret,
+ sub = null, silent = false, refreshToken,
+ ) {
+ let tokenBody;
+ if (!silent) {
+ // Get an OAuth2 code
+ const { code } = await networkSvc.startOauth2(
+ `${serverUrl}/login/oauth/authorize`,
+ {
+ client_id: applicationId,
+ response_type: 'code',
+ redirect_uri: constants.oauth2RedirectUri,
+ },
+ silent,
+ );
+ // Exchange code with token
+ tokenBody = (await networkSvc.request({
+ method: 'POST',
+ url: `${serverUrl}/login/oauth/access_token`,
+ body: {
+ client_id: applicationId,
+ client_secret: applicationSecret,
+ code,
+ grant_type: 'authorization_code',
+ redirect_uri: constants.oauth2RedirectUri,
+ },
+ })).body;
+ } else {
+ // Exchange refreshToken with token
+ tokenBody = (await networkSvc.request({
+ method: 'POST',
+ url: `${serverUrl}/login/oauth/access_token`,
+ body: {
+ client_id: applicationId,
+ client_secret: applicationSecret,
+ refresh_token: refreshToken,
+ grant_type: 'refresh_token',
+ redirect_uri: constants.oauth2RedirectUri,
+ },
+ })).body;
+ }
- // Exchange code with token
- const accessToken = (await networkSvc.request({
- method: 'POST',
- url: `${serverUrl}/login/oauth/access_token`,
- body: {
- client_id: applicationId,
- client_secret: applicationSecret,
- code,
- grant_type: 'authorization_code',
- redirect_uri: constants.oauth2RedirectUri,
- },
- })).body.access_token;
+ const accessToken = tokenBody.access_token;
// Call the user info endpoint
const user = await request({ accessToken, serverUrl }, {
@@ -96,6 +118,8 @@ export default {
const token = {
accessToken,
name: user.username,
+ refreshToken: tokenBody.refresh_token,
+ expiresOn: Date.now() + (tokenBody.expires_in * 1000),
serverUrl,
sub: uniqueSub,
};
@@ -104,6 +128,47 @@ export default {
store.dispatch('data/addGiteaToken', token);
return token;
},
+ // 刷新token
+ async refreshToken(token) {
+ const {
+ serverUrl,
+ applicationId,
+ applicationSecret,
+ sub,
+ } = token;
+ const lastToken = store.getters['data/giteaTokensBySub'][sub];
+ // 兼容旧的没有过期时间
+ if (!lastToken.expiresOn) {
+ await store.dispatch('modal/open', {
+ type: 'providerRedirection',
+ name: 'Gitea',
+ });
+ return this.startOauth2(serverUrl, applicationId, applicationSecret, sub);
+ }
+ // lastToken is not expired
+ if (lastToken.expiresOn > Date.now() + tokenExpirationMargin) {
+ return lastToken;
+ }
+
+ // existing token is about to expire.
+ // Try to get a new token in background
+ try {
+ return await this.startOauth2(
+ serverUrl, applicationId, applicationSecret,
+ sub, true, lastToken.refreshToken,
+ );
+ } catch (err) {
+ // If it fails try to popup a window
+ if (store.state.offline) {
+ throw err;
+ }
+ await store.dispatch('modal/open', {
+ type: 'providerRedirection',
+ name: 'Gitea',
+ });
+ return this.startOauth2(serverUrl, applicationId, applicationSecret, sub);
+ }
+ },
async addAccount(serverUrl, applicationId, applicationSecret, sub = null) {
const token = await this.startOauth2(serverUrl, applicationId, applicationSecret, sub);
badgeSvc.addBadge('addGiteaAccount');
@@ -129,7 +194,8 @@ export default {
projectId,
branch,
}) {
- return request(token, {
+ const refreshedToken = await this.refreshToken(token);
+ return request(refreshedToken, {
url: `repos/${projectId}/git/trees/${branch}`,
params: {
recursive: true,
@@ -147,7 +213,8 @@ export default {
branch,
path,
}) {
- return request(token, {
+ const refreshedToken = await this.refreshToken(token);
+ return request(refreshedToken, {
url: `repos/${projectId}/commits`,
params: {
sha: branch,
@@ -168,7 +235,8 @@ export default {
content,
sha,
}) {
- return request(token, {
+ const refreshedToken = await this.refreshToken(token);
+ return request(refreshedToken, {
method: sha ? 'PUT' : 'POST',
url: `repos/${projectId}/contents/${encodeURIComponent(path)}`,
body: {
@@ -190,7 +258,8 @@ export default {
path,
sha,
}) {
- return request(token, {
+ const refreshedToken = await this.refreshToken(token);
+ return request(refreshedToken, {
method: 'DELETE',
url: `repos/${projectId}/contents/${encodeURIComponent(path)}`,
body: {
@@ -210,7 +279,8 @@ export default {
branch,
path,
}) {
- const { sha, content } = await request(token, {
+ const refreshedToken = await this.refreshToken(token);
+ const { sha, content } = await request(refreshedToken, {
url: `repos/${projectId}/contents/${encodeURIComponent(path)}`,
params: { ref: branch },
});
diff --git a/src/services/providers/helpers/giteeHelper.js b/src/services/providers/helpers/giteeHelper.js
index ffae68ab..59b02227 100644
--- a/src/services/providers/helpers/giteeHelper.js
+++ b/src/services/providers/helpers/giteeHelper.js
@@ -139,7 +139,7 @@ export default {
return this.startOauth2();
}
// lastToken is not expired
- if (lastToken.expiresOn > Date.now() - tokenExpirationMargin) {
+ if (lastToken.expiresOn > Date.now() + tokenExpirationMargin) {
return lastToken;
}
diff --git a/src/services/timeSvc.js b/src/services/timeSvc.js
index 8b157ed2..f8895639 100644
--- a/src/services/timeSvc.js
+++ b/src/services/timeSvc.js
@@ -138,21 +138,21 @@ class RelativeTime {
const hr = Math.round(min / 60);
const day = Math.round(hr / 24);
if (ms < 0) {
- return 'just now';
+ return '刚刚';
} else if (sec < 45) {
- return 'just now';
+ return '刚刚';
} else if (sec < 90) {
- return 'a minute ago';
+ return '1分钟前';
} else if (min < 45) {
- return `${min} minutes ago`;
+ return `${min}分钟前`;
} else if (min < 90) {
- return 'an hour ago';
+ return '1小时前';
} else if (hr < 24) {
- return `${hr} hours ago`;
+ return `${hr}小时前`;
} else if (hr < 36) {
- return 'a day ago';
+ return '1天前';
} else if (day < 30) {
- return `${day} days ago`;
+ return `${day}天前`;
}
return null;
}