diff --git a/src/api/githubApi.ts b/src/api/githubApi.ts index 3435ec37..f88e2b38 100644 --- a/src/api/githubApi.ts +++ b/src/api/githubApi.ts @@ -8,6 +8,9 @@ export const githubRequest = async (endpoint: string, options: RequestInit = {}) try { const response = await fetch(`https://api.github.com${endpoint}`, { + headers: { + Authorization: `Bearer ${token}`, + }, ...options, }); return response.json(); diff --git a/src/constant.ts b/src/constant.ts index c1b67491..913b4794 100644 --- a/src/constant.ts +++ b/src/constant.ts @@ -9,4 +9,5 @@ export const OSS_XLAB_ENDPOINT = 'https://oss.open-digger.cn'; export const HYPERTRONS_CRX_NEW_ISSUE = 'https://github.com/hypertrons/hypertrons-crx/issues/new/choose'; export const HYPERCRX_GITHUB = 'https://github.com/hypertrons/hypertrons-crx'; -export const OSS_URL = 'https://hypercrx-fastpr.oss-cn-beijing.aliyuncs.com/fast-pr-url-rules.cjs'; + +export const FAST_PR_CONFIG_URL = 'https://hypercrx.cn/configs/fast-pr-url-rules.cjs'; diff --git a/src/helpers/gitee-token.ts b/src/helpers/gitee-token.ts index adc2b088..74b14980 100644 --- a/src/helpers/gitee-token.ts +++ b/src/helpers/gitee-token.ts @@ -1,11 +1,43 @@ -export const saveGiteeToken = (token: string) => { - chrome.storage.sync.set({ gitee_token: token }); -}; +const GITEE_TOKEN_KEY = 'gitee_token'; -export const getGiteeToken = (): Promise => { - return new Promise((resolve) => { - chrome.storage.sync.get('gitee_token', (result) => { - resolve(result.gitee_token || null); - }); +export const saveGiteeToken = (token: string, expireAt: number, refreshToken: string) => { + return chrome.storage.sync.set({ + [GITEE_TOKEN_KEY]: { + token, + expireAt, + refreshToken, + }, }); }; + +export const getGiteeToken = async (): Promise => { + const result = await chrome.storage.sync.get(GITEE_TOKEN_KEY); + if (!result || !result[GITEE_TOKEN_KEY]) { + return null; + } + const tokenInfo = result[GITEE_TOKEN_KEY]; + if (!tokenInfo.expireAt || tokenInfo.expireAt > Date.now()) { + return tokenInfo.token || null; + } else { + console.log('Gitee token expired and need refesh'); + const refreshReq = await fetch( + `https://gitee.com/oauth/token?grant_type=refresh_token&refresh_token=${tokenInfo.refreshToken}`, + { method: 'POST' } + ); + const refreshData = await refreshReq.json(); + if (!refreshData) { + console.log('Gitee token refresh failed'); + return null; + } + await saveGiteeToken( + refreshData.access_token, + Date.now() + (refreshData.expires_in - 120) * 1000, + refreshData.refresh_token + ); + return refreshData.access_token; + } +}; + +export const removeGiteeToken = () => { + return chrome.storage.sync.remove(GITEE_TOKEN_KEY); +}; diff --git a/src/helpers/github-token.ts b/src/helpers/github-token.ts index caabb328..0cdf4c5f 100644 --- a/src/helpers/github-token.ts +++ b/src/helpers/github-token.ts @@ -1,11 +1,17 @@ +const GITHUB_TOKEN_KEY = 'github_token'; + export const saveGithubToken = (token: string) => { - chrome.storage.sync.set({ github_token: token }); + return chrome.storage.sync.set({ [GITHUB_TOKEN_KEY]: token }); }; export const getGithubToken = (): Promise => { return new Promise((resolve) => { - chrome.storage.sync.get('github_token', (result) => { - resolve(result.github_token || null); + chrome.storage.sync.get(GITHUB_TOKEN_KEY, (result) => { + resolve(result[GITHUB_TOKEN_KEY] || null); }); }); }; + +export const removeGithubToken = () => { + return chrome.storage.sync.remove(GITHUB_TOKEN_KEY); +}; diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index b14497e3..d3e69495 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -73,52 +73,25 @@ "openrank_icon": "openrank", "contributors_participants_icon": "contributors and participants", "merged_lines_icon": "code lines change", - "github_token_configuration": "GitHub Token Configuration", - "github_token_tooltip": "Enter your GitHub Token here for authentication.", - "github_token_description": "Providing a GitHub Token ensures that HyperCRX can securely and effectively access and operate on your GitHub data for personalized analysis.", - "github_token_how_to_generate": "How to generate a GitHub Token?", - "github_token_step1": "1. Log in to GitHub and go to Settings.", - "github_token_step2": "2. Select Developer settings.", - "github_token_step3": "3. Choose Personal access tokens, click Tokens (classic), then Generate a personal access token.", - "github_token_step4": "4. Set token details:", - "github_token_note": "Note", - "github_token_note_description": "A descriptive name, e.g., \"HyperCRX Token\".", - "github_token_expiration": "Expiration", - "github_token_expiration_description": "Choose the validity period.", - "github_token_scopes": "Scopes", - "github_token_scopes_description": "Select permission scopes, such as repo and workflow.", - "github_token_step5": "5. Click the Generate token button.", - "github_token_step6": "6. Copy the generated token and paste it into the input box below.", - "github_token_placeholder": "GitHub Token", - "github_token_save": "Save", - "github_token_edit": "Edit", - "github_token_test": "Test Token", - "github_token_error_empty": "Token cannot be empty", - "github_token_success_save": "Token saved successfully", - "github_token_success_valid": "Token is valid. Username: {{username}}", - "github_token_error_invalid": "Invalid token or request failed", - "gitee_token_configuration": "Gitee Token Configuration", - "gitee_token_tooltip": "Enter your Gitee Token here for authentication.", - "gitee_token_description": "Providing a Gitee Token ensures that HyperCRX can securely and effectively access and operate on your Gitee data for personalized analysis.", - "gitee_token_how_to_generate": "How to generate a Gitee Token?", - "gitee_token_step1": "1. Log in to Gitee and go to Personal Settings.", - "gitee_token_step2": "2. Find and click on the Private Token option in the left menu.", - "gitee_token_step3": "3. Click the Generate New Token button.", - "gitee_token_step4": "4. Set token details:", - "gitee_token_note": "Note", - "gitee_token_note_description": "A descriptive name, e.g., \"HyperCRX Token\".", - "gitee_token_scopes": "Scopes", - "gitee_token_scopes_description": "Select permission scopes, such as user_info and projects.", - "gitee_token_step5": "5. Click the Generate token button.", - "gitee_token_step6": "6. Copy the generated token and paste it into the input box below.", - "gitee_token_placeholder": "Gitee Token", - "gitee_token_save": "Save", - "gitee_token_edit": "Edit", - "gitee_token_test": "Test Token", - "gitee_token_error_empty": "Token cannot be empty", - "gitee_token_success_save": "Token saved successfully", - "gitee_token_success_valid": "Token is valid. Username: {{username}}", - "gitee_token_error_invalid": "Invalid token or request failed", + + "github_account_configuration": "GitHub Account Binding", + "github_account_tooltip": "Authorize HyperCRX to access your GitHub account.", + "github_account_description": "Authorizing your GitHub account allows HyperCRX to securely and efficiently access GitHub data and perform other operations on your behalf, such as FastPR. The authorization information will only be securely stored in your browser; HyperCRX will not store or leak your authorization information.", + "github_account_bind": "Bind Account", + "github_account_unbind": "Unbind Account", + "github_account_no_bind": "No binding account found.", + "github_account_binded": "🎉Bind with GitHub account: {{username}}", + "github_account_bind_fail": "GitHub account binding failed.", + + "gitee_account_configuration": "Gitee Account Binding", + "gitee_account_tooltip": "Authorize HyperCRX to access your Gitee account.", + "gitee_account_description": "Authorizing your Gitee account allows HyperCRX to securely and efficiently access Gitee data and perform other operations on your behalf, such as FastPR. The authorization information will only be securely stored in your browser; HyperCRX will not store or leak your authorization information.", + "gitee_account_bind": "Bind Account", + "gitee_account_unbind": "Unbind Account", + "gitee_account_no_bind": "No binding account found.", + "gitee_account_binded": "🎉Bind with Gitee account: {{username}}", + "gitee_account_bind_fail": "Gitee account binding failed.", + "fast_pr": "FastPR", "pr_title_label": "PR Title", "pr_title_rule": "Please enter the PR title", @@ -151,6 +124,6 @@ "success_create_pr": "PR created successfully.\nPR URL: {{url}}", "error_get_user_info": "Failed to get user info: {{status}}", "error_get_file": "The path is a directory, not a file.", - "github_token_not_found": "GitHub token not found.\nPlease enter the token in the Settings page of the extension.", - "gitee_token_not_found": "Gitee token not found.\nPlease enter the token in the Settings page of the extension." + "github_token_not_found": "GitHub token not found.\nPlease bind your account in the Settings page of the extension.", + "gitee_token_not_found": "Gitee token not found.\nPlease bind your account in the Settings page of the extension." } diff --git a/src/locales/zh_CN/translation.json b/src/locales/zh_CN/translation.json index 3f912aea..36dee6a4 100644 --- a/src/locales/zh_CN/translation.json +++ b/src/locales/zh_CN/translation.json @@ -72,52 +72,25 @@ "openrank_icon": "openrank值", "contributors_participants_icon": "contributors和participants数", "merged_lines_icon": "代码变化量", - "github_token_configuration": "GitHub 令牌配置", - "github_token_tooltip": "在此输入您的 GitHub 令牌以进行身份验证。", - "github_token_description": "提供 GitHub 令牌可确保 HyperCRX 能够安全有效地访问和操作您的 GitHub 数据以进行个性化分析。", - "github_token_how_to_generate": "如何生成 GitHub 令牌?", - "github_token_step1": "1. 登录 GitHub 并进入设置。", - "github_token_step2": "2. 选择开发者设置。", - "github_token_step3": "3. 选择个人访问令牌,Tokens (classic),然后生成个人访问令牌。", - "github_token_step4": "4. 设置令牌详细信息:", - "github_token_note": "注意", - "github_token_note_description": "描述性名称,例如:“HyperCRX Token”。", - "github_token_expiration": "过期时间", - "github_token_expiration_description": "选择有效期。", - "github_token_scopes": "权限范围", - "github_token_scopes_description": "选择权限范围,例如 repo 和 workflow。", - "github_token_step5": "5. 点击生成令牌按钮。", - "github_token_step6": "6. 复制生成的令牌并将其粘贴到下面的输入框中。", - "github_token_placeholder": "GitHub 令牌", - "github_token_save": "保存", - "github_token_edit": "编辑", - "github_token_test": "测试令牌", - "github_token_error_empty": "令牌不能为空", - "github_token_success_save": "令牌保存成功", - "github_token_success_valid": "令牌有效。用户名:{{username}}", - "github_token_error_invalid": "令牌无效或请求失败", - "gitee_token_configuration": "Gitee 令牌配置", - "gitee_token_tooltip": "在此输入您的 Gitee 令牌以进行身份验证。", - "gitee_token_description": "提供 Gitee 令牌可确保 HyperCRX 能够安全有效地访问和操作您的 Gitee 数据以进行个性化分析。", - "gitee_token_how_to_generate": "如何生成 Gitee 令牌?", - "gitee_token_step1": "1. 登录 Gitee 并进入设置。", - "gitee_token_step2": "2. 在左侧菜单中找到并点击 私人令牌 选项。", - "gitee_token_step3": "3. 点击 生成新令牌 按钮。", - "gitee_token_step4": "4. 设置令牌详细信息:", - "gitee_token_note": "注意", - "gitee_token_note_description": "描述性名称,例如:“HyperCRX Token”。", - "gitee_token_scopes": "权限范围", - "gitee_token_scopes_description": "选择权限范围,例如 user_info 和 projects。", - "gitee_token_step5": "5. 点击生成令牌按钮。", - "gitee_token_step6": "6. 复制生成的令牌并将其粘贴到下面的输入框中。", - "gitee_token_placeholder": "Gitee 令牌", - "gitee_token_save": "保存", - "gitee_token_edit": "编辑", - "gitee_token_test": "测试令牌", - "gitee_token_error_empty": "令牌不能为空", - "gitee_token_success_save": "令牌保存成功", - "gitee_token_success_valid": "令牌有效。用户名:{{username}}", - "gitee_token_error_invalid": "令牌无效或请求失败", + + "github_account_configuration": "绑定 GitHub 账号", + "github_account_tooltip": "绑定 GitHub 账号", + "github_account_description": "为 HyperCRX 授权您的 GitHub 账号,可用于安全高效获取 GitHub 数据以及代理您的一些操作,例如 FastPR 功能。授权信息将安全的存储在您的浏览器本地,HyperCRX 并不会远程存储和泄露您的授权信息。", + "github_account_bind": "绑定账号", + "github_account_unbind": "解绑账号", + "github_account_no_bind": "当前无绑定账号", + "github_account_binded": "🎉当前绑定的 GitHub 账号为:{{username}}", + "github_account_bind_fail": "GitHub 账号绑定失败", + + "gitee_account_configuration": "绑定 Gitee 账号", + "gitee_account_tooltip": "绑定 Gitee 账号", + "gitee_account_description": "为 HyperCRX 授权您的 Gitee 账号,可用于安全高效获取 Gitee 数据以及代理您的一些操作,例如 FastPR 功能。授权信息将安全的存储在您的浏览器本地,HyperCRX 并不会远程存储和泄露您的授权信息。", + "gitee_account_bind": "绑定账号", + "gitee_account_unbind": "解绑账号", + "gitee_account_no_bind": "当前无绑定账号", + "gitee_account_binded": "🎉当前绑定的 Gitee 账号为:{{username}}", + "gitee_account_bind_fail": "Gitee 账号绑定失败", + "fast_pr": "FastPR", "pr_title_label": "PR 标题", "pr_title_rule": "请输入 PR 的标题", @@ -150,6 +123,6 @@ "success_create_pr": "PR创建成功。\nPR 地址为: {{url}}", "error_get_user_info": "获取用户信息失败:{{status}}", "error_get_file": "该路径是一个目录,而不是文件", - "github_token_not_found": "GitHub 的 token 没有找到。\n请记得在扩展程序的设置页面输入 GitHub token。", - "gitee_token_not_found": "Gitee 的 token 没有找到。\n请记得在扩展程序的设置页面输入 Gitee token。" + "github_token_not_found": "GitHub 的 token 没有找到。\n请记得在扩展程序的设置页面中绑定您的账号。", + "gitee_token_not_found": "Gitee 的 token 没有找到。\n请记得在扩展程序的设置页面中绑定您的账号。" } diff --git a/src/manifest.json b/src/manifest.json index f69f83e0..ffe9b33f 100755 --- a/src/manifest.json +++ b/src/manifest.json @@ -31,7 +31,7 @@ "matches": [""] } ], - "permissions": ["storage"], + "permissions": ["storage", "identity"], "host_permissions": [""], "content_security_policy": { "extension_pages": "script-src 'self'; object-src 'self';" diff --git a/src/pages/Options/Options.css b/src/pages/Options/Options.css index 1d1f3add..749682f5 100644 --- a/src/pages/Options/Options.css +++ b/src/pages/Options/Options.css @@ -102,8 +102,8 @@ a { } .token-options button { - padding: 8px 16px; - margin: 0 25px 20px; + padding: 8px 8px; + margin: 0 10px 20px; background-color: #007bff; color: #fff; border: none; diff --git a/src/pages/Options/components/GitHubToken.tsx b/src/pages/Options/components/GitHubToken.tsx index 183d90a7..4b3f9f4e 100644 --- a/src/pages/Options/components/GitHubToken.tsx +++ b/src/pages/Options/components/GitHubToken.tsx @@ -3,52 +3,71 @@ import TooltipTrigger from '../../../components/TooltipTrigger'; import { saveGithubToken, getGithubToken, githubRequest } from '../../../api/githubApi'; import { message } from 'antd'; import { useTranslation } from 'react-i18next'; +import { removeGithubToken } from '../../../helpers/github-token'; const GitHubToken = () => { - const [token, setToken] = useState(''); - const [isCollapsed, setIsCollapsed] = useState(true); - const [isEditing, setIsEditing] = useState(false); - const { t } = useTranslation(); + const [inputValue, setInputValue] = useState(''); + const { t, i18n } = useTranslation(); const inputRef = useRef(null); const fetchToken = async () => { const storedToken = await getGithubToken(); if (storedToken) { - setToken(storedToken); + updateInputValue(); } }; - useEffect(() => { - fetchToken(); - }, []); - const handleSave = () => { - if (!token.trim()) { - showMessage(t('github_token_error_empty'), 'error'); - return; + const updateInputValue = async () => { + const userData = await githubRequest('/user'); + if (userData && userData.login) { + setInputValue(t('github_account_binded', { username: userData.login })); } - saveGithubToken(token); - showMessage(t('github_token_success_save'), 'success'); - setIsEditing(false); }; - const handleEdit = () => { - setIsEditing(true); - }; + useEffect(() => { + fetchToken(); + }, []); - const handleTestToken = async () => { - const userData = await githubRequest('/user', { - headers: { Authorization: `Bearer ${token}` }, - }); + useEffect(() => { + fetchToken(); + }, [i18n.language]); - if (userData === null || userData.message) { - showMessage(t('github_token_error_invalid'), 'error'); - } else { - showMessage(t('github_token_success_valid', { username: userData.login }), 'success'); - } + const handleBindAccount = async () => { + const clientId = 'Ov23liyofMsuQYwtfGLb'; + const redirectUri = 'https://oauth.hypercrx.cn/github'; + const callback = chrome.identity.getRedirectURL(); + const scope = encodeURIComponent('read:user, public_repo'); + const authUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=token&state=${callback}`; + + chrome.identity.launchWebAuthFlow( + { + url: authUrl, + interactive: true, + }, + async (redirectUrl) => { + if (!redirectUrl) { + console.error(chrome.runtime.lastError ? chrome.runtime.lastError.message : 'Authorization failed.'); + return; + } + const ret = new URL(redirectUrl).searchParams.get('ret'); + if (!ret) { + console.error('Ret not returned in callback URL, check the server config'); + return; + } + const retData = JSON.parse(decodeURIComponent(ret)); + if (!retData.access_token) { + console.error('Invalid token data returned, check the server config'); + showMessage(t('github_account_bind_fail'), 'error'); + return; + } + await saveGithubToken(retData.access_token); + updateInputValue(); + } + ); }; - const obfuscateToken = (token: string): string => { - if (token.length <= 4) return token; - return `${token[0]}${'*'.repeat(token.length - 2)}${token[token.length - 1]}`; + const handleUnbindAccount = async () => { + await removeGithubToken(); + setInputValue(''); }; const showMessage = (content: string, type: 'success' | 'error') => { @@ -66,67 +85,25 @@ const GitHubToken = () => { return (
-

{t('github_token_configuration')}

- -
-

{t('github_token_description')}

-
-
setIsCollapsed(!isCollapsed)} - style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} - > -

{t('github_token_how_to_generate')}

- {isCollapsed ? '▶' : '▼'} -
- {!isCollapsed && ( -
-
    -
  1. {t('github_token_step1')}
  2. -
  3. {t('github_token_step2')}
  4. -
  5. {t('github_token_step3')}
  6. -
  7. - {t('github_token_step4')} -
      -
    • - {t('github_token_note')}: {t('github_token_note_description')} -
    • -
    • - {t('github_token_expiration')}: {t('github_token_expiration_description')} -
    • -
    • - {t('github_token_scopes')}: {t('github_token_scopes_description')} -
    • -
    -
  8. -
  9. {t('github_token_step5')}
  10. -
  11. {t('github_token_step6')}
  12. -
-
- )} +

{t('github_account_configuration')}

+
+

{t('github_account_description')}

setToken(e.target.value)} - placeholder={t('github_token_placeholder')} + value={inputValue} + placeholder={t('github_account_no_bind')} style={{ marginRight: '10px', flex: 1 }} - disabled={!isEditing} + disabled={true} /> - {isEditing ? ( - - ) : ( - - )} - +
diff --git a/src/pages/Options/components/GiteeToken.tsx b/src/pages/Options/components/GiteeToken.tsx index c684c8ee..97337ab7 100644 --- a/src/pages/Options/components/GiteeToken.tsx +++ b/src/pages/Options/components/GiteeToken.tsx @@ -3,52 +3,74 @@ import TooltipTrigger from '../../../components/TooltipTrigger'; import { saveGiteeToken, getGiteeToken, giteeRequest } from '../../../api/giteeApi'; import { message } from 'antd'; import { useTranslation } from 'react-i18next'; +import { removeGiteeToken } from '../../../helpers/gitee-token'; const GiteeToken = () => { - const [token, setToken] = useState(''); - const [isCollapsed, setIsCollapsed] = useState(true); - const [isEditing, setIsEditing] = useState(false); - const { t } = useTranslation(); + const [inputValue, setInputValue] = useState(''); + const { t, i18n } = useTranslation(); const inputRef = useRef(null); + const fetchToken = async () => { const storedToken = await getGiteeToken(); if (storedToken) { - setToken(storedToken); + updateInputValue(); } }; - useEffect(() => { - fetchToken(); - }, []); - const handleSave = () => { - if (!token.trim()) { - showMessage(t('gitee_token_error_empty'), 'error'); - return; + const updateInputValue = async () => { + const userData = await giteeRequest('user'); + if (userData && userData.login) { + setInputValue(t('gitee_account_binded', { username: userData.login })); } - saveGiteeToken(token); - showMessage(t('gitee_token_success_save'), 'success'); - setIsEditing(false); }; - const handleEdit = () => { - setIsEditing(true); - }; + useEffect(() => { + fetchToken(); + }, []); - const handleTestToken = async () => { - const userData = await giteeRequest('/user', { - headers: { access_token: `Bearer ${token}` }, - }); + useEffect(() => { + fetchToken(); + }, [i18n.language]); - if (userData === null || userData.message) { - showMessage(t('gitee_token_error_invalid'), 'error'); - } else { - showMessage(t('gitee_token_success_valid', { username: userData.login }), 'success'); - } + const handleBindAccount = async () => { + const clientId = 'e76727820aa539f3a59399d0bc48156df2057e81774617e433eeb49d1dad97b3'; + const redirectUri = 'https://oauth.hypercrx.cn/gitee'; + const scope = encodeURIComponent('user_info projects pull_requests issues notes'); + const callback = chrome.identity.getRedirectURL(); + const authUrl = `https://gitee.com/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&state=${callback}`; + + chrome.identity.launchWebAuthFlow( + { + url: authUrl, + interactive: true, + }, + async function (redirectUrl) { + if (!redirectUrl) { + console.error(chrome.runtime.lastError ? chrome.runtime.lastError.message : 'Authorization failed.'); + return; + } + const ret = new URL(redirectUrl).searchParams.get('ret'); + if (!ret) { + console.error('Ret not returned in callback URL, check the server config'); + showMessage(t('gitee_account_bind_fail'), 'error'); + return; + } + const retData = JSON.parse(decodeURIComponent(ret)); + if (!retData.access_token || !retData.refresh_token || !retData.expires_in) { + console.error('Invalid token data returned, check the server config'); + showMessage(t('gitee_account_bind_fail'), 'error'); + return; + } + const expireAt = Date.now() + (retData.expires_in - 120) * 1000; + await saveGiteeToken(retData.access_token, expireAt, retData.refresh_token); + updateInputValue(); + } + ); }; - const obfuscateToken = (token: string): string => { - if (token.length <= 4) return token; - return `${token[0]}${'*'.repeat(token.length - 2)}${token[token.length - 1]}`; + const handleUnbindAccount = async () => { + await removeGiteeToken(); + setInputValue(''); }; const showMessage = (content: string, type: 'success' | 'error') => { @@ -66,64 +88,25 @@ const GiteeToken = () => { return (
-

{t('gitee_token_configuration')}

- -
-

{t('gitee_token_description')}

-
-
setIsCollapsed(!isCollapsed)} - style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} - > -

{t('gitee_token_how_to_generate')}

- {isCollapsed ? '▶' : '▼'} -
- {!isCollapsed && ( -
-
    -
  1. {t('gitee_token_step1')}
  2. -
  3. {t('gitee_token_step2')}
  4. -
  5. {t('gitee_token_step3')}
  6. -
  7. - {t('gitee_token_step4')} -
      -
    • - {t('gitee_token_note')}: {t('gitee_token_note_description')} -
    • -
    • - {t('gitee_token_scopes')}: {t('gitee_token_scopes_description')} -
    • -
    -
  8. -
  9. {t('gitee_token_step5')}
  10. -
  11. {t('gitee_token_step6')}
  12. -
-
- )} +

{t('gitee_account_configuration')}

+
+

{t('gitee_account_description')}

setToken(e.target.value)} - placeholder={t('gitee_token_placeholder')} + value={inputValue} + placeholder={t('gitee_account_no_bind')} style={{ marginRight: '10px', flex: 1 }} - disabled={!isEditing} + disabled={true} /> - {isEditing ? ( - - ) : ( - - )} - +
diff --git a/src/pages/Sandbox/index.jsx b/src/pages/Sandbox/index.jsx index ec1526a2..94d891d8 100644 --- a/src/pages/Sandbox/index.jsx +++ b/src/pages/Sandbox/index.jsx @@ -1,11 +1,11 @@ import React, { useEffect } from 'react'; -import { OSS_URL } from '../../constant'; +import { FAST_PR_CONFIG_URL } from '../../constant'; import { createRoot } from 'react-dom/client'; const SandboxApp = () => { useEffect(() => { const fetchAndExecuteScript = () => { - fetch(OSS_URL) + fetch(FAST_PR_CONFIG_URL) .then((response) => response.text()) .then((scriptContent) => { const func = new Function(scriptContent);