From 37d1ca614712ae90dfdf9ce490dd22b5c25d95c4 Mon Sep 17 00:00:00 2001 From: QLHazyCoder <2825305047@qq.com> Date: Fri, 24 Apr 2026 10:29:37 +0800 Subject: [PATCH 01/12] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E8=B4=A1?= =?UTF-8?q?=E7=8C=AE=E6=A8=A1=E5=BC=8F=E7=9B=B8=E5=85=B3URL=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8A=E4=BC=A0=E9=A1=B5=E9=9D=A2=E5=92=8C?= =?UTF-8?q?=E5=AE=98=E7=BD=91=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sidepanel/contribution-mode.js | 19 ++++- sidepanel/sidepanel.html | 94 ++++++++++++--------- sidepanel/sidepanel.js | 5 +- tests/sidepanel-contribution-button.test.js | 2 +- tests/sidepanel-contribution-mode.test.js | 5 +- 5 files changed, 79 insertions(+), 46 deletions(-) diff --git a/sidepanel/contribution-mode.js b/sidepanel/contribution-mode.js index c54081c..d6331b5 100644 --- a/sidepanel/contribution-mode.js +++ b/sidepanel/contribution-mode.js @@ -12,7 +12,8 @@ constants = {}, } = context; - const contributionUploadUrl = constants.contributionUploadUrl || 'https://apikey.qzz.io'; + const contributionPortalUrl = constants.contributionPortalUrl || 'https://apikey.qzz.io'; + const contributionUploadUrl = constants.contributionUploadUrl || 'https://apikey.qzz.io/upload'; const pollIntervalMs = Math.max(1500, Math.floor(Number(constants.pollIntervalMs) || 2500)); const hiddenRows = [ @@ -175,10 +176,22 @@ return normalizeString(currentState.contributionStatusMessage) || DEFAULT_COPY; } + function getContributionPortalPageUrl() { + return normalizeString(contributionPortalUrl); + } + function getContributionUploadPageUrl() { return normalizeString(contributionUploadUrl); } + function openContributionPortalPage() { + const targetUrl = getContributionPortalPageUrl(); + if (!targetUrl) { + return; + } + helpers.openExternalUrl?.(targetUrl); + } + function openContributionUploadPage() { const targetUrl = getContributionUploadPageUrl(); if (!targetUrl) { @@ -375,9 +388,9 @@ } actionInFlight = true; try { - openContributionUploadPage(); + openContributionPortalPage(); } catch (error) { - helpers.showToast?.(`打开上传页面失败:${error.message}`, 'error'); + helpers.showToast?.(`打开官网页面失败:${error.message}`, 'error'); } render(); try { diff --git a/sidepanel/sidepanel.html b/sidepanel/sidepanel.html index 63f7ab0..b400c81 100644 --- a/sidepanel/sidepanel.html +++ b/sidepanel/sidepanel.html @@ -16,8 +16,7 @@
- + aria-pressed="false" title="进入贡献模式并打开官网页">贡献/使用教程 @@ -120,14 +119,16 @@ CPA
-

当前账号将用于支持项目维护。扩展会自动申请贡献登录地址并持续跟踪授权状态;如检测到回调地址,会自动提交,无需手动复制。

+

+ 当前账号将用于支持项目维护。扩展会自动申请贡献登录地址并持续跟踪授权状态;如检测到回调地址,会自动提交,无需手动复制。

贡献昵称
QQ - +
@@ -190,8 +191,7 @@
-

请更新前导出配置

+

一定请先导出配置,再执行更新

diff --git a/tests/sidepanel-icloud-manager.test.js b/tests/sidepanel-icloud-manager.test.js index 2456f65..7efff50 100644 --- a/tests/sidepanel-icloud-manager.test.js +++ b/tests/sidepanel-icloud-manager.test.js @@ -23,7 +23,7 @@ test('update card highlights exporting config before upgrade', () => { const html = fs.readFileSync('sidepanel/sidepanel.html', 'utf8'); const css = fs.readFileSync('sidepanel/sidepanel.css', 'utf8'); - assert.match(html, /

请更新前导出配置<\/p>/); + assert.match(html, /

一定请先导出配置,再执行更新<\/p>/); assert.match(css, /\.update-card-reminder\s*\{/); assert.match(css, /font-weight:\s*700;/); assert.match(css, /color:\s*var\(--orange\);/); From bf91af35760fbeec831a4fb7048b4e1bcd3ce0c0 Mon Sep 17 00:00:00 2001 From: QLHazyCoder <2825305047@qq.com> Date: Sat, 25 Apr 2026 01:50:48 +0800 Subject: [PATCH 12/12] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=20Cloudflare?= =?UTF-8?q?=20Temp=20Email=20=E4=BD=BF=E7=94=A8=E8=AF=B4=E6=98=8E=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3=E9=93=BE=E6=8E=A5=E5=92=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=AD=A5=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/使用教程.md | 51 +++++++++++++-- sidepanel/sidepanel.js | 47 ++------------ ...dflare-temp-email-random-subdomain.test.js | 64 ++++++------------- 3 files changed, 69 insertions(+), 93 deletions(-) diff --git a/docs/使用教程.md b/docs/使用教程.md index d23a634..d419c53 100644 --- a/docs/使用教程.md +++ b/docs/使用教程.md @@ -1,11 +1,10 @@ -# Codex 注册扩展相关项目、更新、QQ 邮箱切换与 Clash Verge 配置教程 - 本教程用于说明相关项目地址、扩展更新方式、`QQ 邮箱`切换邮箱的使用方法,以及 `Clash Verge` 的 `🔁 非港轮询` 配置方法。 ## 适用场景 - 需要拉取并部署 `cpa` 或 `sub2api` 项目 - 已经安装本扩展,想更新到最新版本 +- 需要把 `Cloudflare Temp Email` 用作 `邮箱生成` 或 `邮箱服务` - 需要临时切换 `QQ 邮箱` 地址继续使用 - 需要在 `Clash Verge` 中启用 `🔁 非港轮询` @@ -14,6 +13,7 @@ - 可以访问 `GitHub` - 已安装好的扩展文件夹 - 可以打开浏览器的 `扩展程序管理` 页面 +- 已准备好 `Cloudflare Temp Email` 后端地址;如需随机子域,域名解析也已配置完成 - 一个可正常登录的 `QQ 邮箱` - 如需部署 `cpa`,部署环境必须可以访问 `OpenAI` - 已安装 `Clash Verge`,并已导入可用订阅 @@ -60,7 +60,42 @@ 找到该扩展后,手动点击一次 `重新加载`。 这一步一定要做,否则浏览器可能仍在使用旧版本。 -### 第三部分:`QQ 邮箱`切换邮箱使用教程 +### 第三部分:`Cloudflare Temp Email` 使用说明 + +1. 先确认当前用途 + `Cloudflare Temp Email` 可以作为 `邮箱生成`,也可以作为 `邮箱服务`。 + 如果两边都选择了它,就需要把两套配置都填完整。 + +2. 填写 `Temp API` + 这里填写 `Cloudflare Temp Email` 后端地址,例如 `https://your-worker-domain`。 + 不论你是拿它来生成邮箱,还是接收转发邮件,这一项都需要先配好。 + +3. 作为 `邮箱生成` 使用时填写 `Admin Auth` + `Admin Auth` 对应后端的 `admin auth`。 + 只有在 `邮箱生成 = Cloudflare Temp Email` 时,这一项才是必填。 + +4. 按需填写 `Custom Auth` + `Custom Auth` 只在站点额外开启访问密码时才需要填写。 + 如果没有开启额外访问密码,留空即可。 + 这一项不会替代 `Admin Auth`。 + +5. 配置 `Temp 域名` + 这里填写允许创建邮箱的基础域名。 + 即使开启了 `随机子域`,这里仍然填写基础域名,而不是随机出来的子域名。 + +6. 按需开启 `随机子域` + `随机子域` 只在 `邮箱生成 = Cloudflare Temp Email` 时使用。 + 后端需要提前配置 `RANDOM_SUBDOMAIN_DOMAINS`,Cloudflare DNS 也需要设置 `MX *`。 + 相关说明可参考 [Issue #942](https://github.com/dreamhunter2333/cloudflare_temp_email/issues/942)。 + +7. 作为 `邮箱服务` 使用时填写 `邮件接收` + 只有在 `邮箱服务 = Cloudflare Temp Email` 时,这一项才需要填写。 + 这里填写真正用于接收转发邮件的目标邮箱。 + +8. 查看搭建参考 + 如果你还没有部署后端,可参考 [LINUX DO 教程](https://linux.do/t/topic/316819)。 + +### 第四部分:`QQ 邮箱`切换邮箱使用教程 1. 登录 `QQ 邮箱` 先登录你当前正在使用的 `QQ 邮箱` 账号。 @@ -79,13 +114,15 @@ 这两个邮箱地址使用完成后,可以直接删除。 删除后再次创建新的英文邮箱和 `Foxmail` 邮箱,即可重复注册使用。 -### 第四部分:配置 `Clash Verge` 的 `🔁 非港轮询` +### 第五部分:配置 `Clash Verge` 的 `🔁 非港轮询` #### 第一步:添加扩展脚本 1. 打开 `Clash Verge`,进入左侧的 `订阅`(`Profiles`)界面。 -2. 在右上角或对应位置找到并双击打开 `全局扩展脚本`(`Merge/Script`)。 +2. 在右上角或对应位置找到并双击打开 `全局扩展脚本`。 +![05d15cd026ec21d0cffde04ad0d1a6c9](https://apikey.qzz.io/content-assets/library/2026/04/20260424-163252--05d15cd026ec21d0cffde04ad0d1a6c9--0a59ba73acff.png) 3. 将里面的内容全部清空,替换为下方脚本代码。 +![2026 04 25 003728](https://apikey.qzz.io/content-assets/library/2026/04/20260424-163745--2026-04-25-003728--59bf89f34367.png) 4. 点击保存,使用右上角保存按钮或按 `Ctrl+S`。 💻 脚本代码(如果遇到格式错误,可让豆包帮你修复后再粘贴) @@ -184,7 +221,7 @@ function main(config, profileName) { 3. 在对应下拉框中选择 `🔁 非港轮询`。 4. 确认右上角的 `代理模式`(`Mode`)已经设置为 `规则模式`(`Rule`)。 5. 确认左侧 `设置` 中的 `系统代理`(`System Proxy`)已经开启。 - +![2026 04 25 003703](https://apikey.qzz.io/content-assets/library/2026/04/20260424-163745--2026-04-25-003703--21e892504b82.png) ## 常见问题 ### 为什么第十步显示认证成功,但没有认证文件? @@ -206,6 +243,8 @@ function main(config, profileName) { ## 注意事项 - 不论使用哪种方式更新扩展,更新完成后都必须在浏览器的 `扩展程序管理` 页面重新加载一次该扩展。 +- 如果同时把 `Cloudflare Temp Email` 用作 `邮箱生成` 和 `邮箱服务`,请同时检查 `Admin Auth`、`Custom Auth`、`Temp 域名` 和 `邮件接收` 是否都已配置。 +- 开启 `随机子域` 前,请先确认后端已经配置 `RANDOM_SUBDOMAIN_DOMAINS`,并且 Cloudflare DNS 已完成 `MX *` 设置。 - 如需部署 `cpa`,请先确认部署环境可以访问 `OpenAI`,否则可能出现第十步认证成功但没有认证文件的问题。 - `QQ 邮箱`切换邮箱时,建议在使用完成后及时删除,再重新创建,避免混淆当前正在使用的邮箱地址。 - 使用 `git pull` 更新扩展是最方便、最推荐的方式。 diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index 4f47854..c7f7b63 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -629,8 +629,6 @@ const LOG_LEVEL_LABELS = { }; const CLOUDFLARE_TEMP_EMAIL_REPOSITORY_URL = 'https://github.com/dreamhunter2333/cloudflare_temp_email'; -const CLOUDFLARE_TEMP_EMAIL_BUILD_TUTORIAL_URL = 'https://linux.do/t/topic/316819'; -const CLOUDFLARE_TEMP_EMAIL_RANDOM_SUBDOMAIN_ISSUE_URL = 'https://github.com/dreamhunter2333/cloudflare_temp_email/issues/942'; function usesGeneratedAliasMailProvider( provider, @@ -2257,45 +2255,12 @@ function openReleaseListPage() { openExternalUrl(getReleaseListUrl()); } -function buildCloudflareTempEmailUsageGuideModalConfig() { - const useCloudflareTempEmailProvider = String(selectMailProvider?.value || '').trim().toLowerCase() === 'cloudflare-temp-email'; - const useCloudflareTempEmailGenerator = getSelectedEmailGenerator() === 'cloudflare-temp-email'; - let alertText = '当前还没有把 Cloudflare Temp Email 选为邮箱服务或邮箱生成器。下面说明同时覆盖“生成邮箱”和“接收转发邮件”两种用法。'; - if (useCloudflareTempEmailProvider && useCloudflareTempEmailGenerator) { - alertText = '当前同时把 Cloudflare Temp Email 用作“邮箱服务”和“邮箱生成器”。请同时配置生成邮箱和接收转发两套必填项。'; - } else if (useCloudflareTempEmailProvider) { - alertText = '当前把 Cloudflare Temp Email 用作“邮箱服务”。重点填写 Temp API、Custom Auth 和 邮件接收。'; - } else if (useCloudflareTempEmailGenerator) { - alertText = '当前把 Cloudflare Temp Email 用作“邮箱生成器”。重点填写 Temp API、Admin Auth 和 Temp 域名;随机子域按需开启。'; +function openCloudflareTempEmailUsageGuidePage() { + const targetUrl = getContributionPortalUrl(); + if (!targetUrl) { + return; } - - return { - title: 'Cloudflare Temp Email 使用教程', - alert: { text: alertText }, - messageHtml: `Temp API:填写 Cloudflare Temp Email 后端地址。

-Admin Auth:填写后端 admin auth。
-仅在“邮箱生成 = Cloudflare Temp Email”时必填。

-Custom Auth:仅当站点额外开启访问密码时填写。没有开启就留空。

-Temp 域名:填写允许创建的基础域名。启用随机子域时,这里仍然填写基础域名。

-随机子域:仅在“邮箱生成 = Cloudflare Temp Email”时使用。
-后端需要已配置 RANDOM_SUBDOMAIN_DOMAINS。
-CF DNS 需要设置 MX *,参考 Issue #942

-邮件接收:仅在“邮箱服务 = Cloudflare Temp Email”时填写。
-这里填写真正接收转发邮件的目标邮箱。

-搭建教程:LINUX DO 教程。`, - }; -} - -function showCloudflareTempEmailUsageGuide() { - const modalConfig = buildCloudflareTempEmailUsageGuideModalConfig(); - return openActionModal({ - title: modalConfig.title, - messageHtml: modalConfig.messageHtml, - alert: modalConfig.alert, - actions: [ - { id: 'ok', label: '知道了', variant: 'btn-primary' }, - ], - }); + openExternalUrl(targetUrl); } function openCloudflareTempEmailRepositoryPage() { @@ -4243,7 +4208,7 @@ btnRepoHome?.addEventListener('click', () => { }); btnCloudflareTempEmailUsageGuide?.addEventListener('click', () => { - showCloudflareTempEmailUsageGuide(); + openCloudflareTempEmailUsageGuidePage(); }); btnCloudflareTempEmailGithub?.addEventListener('click', () => { diff --git a/tests/sidepanel-cloudflare-temp-email-random-subdomain.test.js b/tests/sidepanel-cloudflare-temp-email-random-subdomain.test.js index e969761..afa859f 100644 --- a/tests/sidepanel-cloudflare-temp-email-random-subdomain.test.js +++ b/tests/sidepanel-cloudflare-temp-email-random-subdomain.test.js @@ -70,68 +70,40 @@ test('sidepanel modal message preserves line breaks and supports inline links', assert.match(css, /\.modal-message a,\s*[\s\S]*\.modal-alert a/); }); -test('buildCloudflareTempEmailUsageGuideModalConfig returns a modal payload with inline links for generator mode', () => { - const bundle = extractFunction('buildCloudflareTempEmailUsageGuideModalConfig'); +test('openCloudflareTempEmailUsageGuidePage opens the contribution portal home page', () => { + const bundle = extractFunction('openCloudflareTempEmailUsageGuidePage'); const api = new Function(` -const selectMailProvider = { value: '163' }; -const selectEmailGenerator = { value: 'cloudflare-temp-email' }; -const CLOUDFLARE_TEMP_EMAIL_BUILD_TUTORIAL_URL = 'https://linux.do/t/topic/316819'; -const CLOUDFLARE_TEMP_EMAIL_RANDOM_SUBDOMAIN_ISSUE_URL = 'https://github.com/dreamhunter2333/cloudflare_temp_email/issues/942'; -function getSelectedEmailGenerator() { return String(selectEmailGenerator.value || '').trim().toLowerCase(); } +const openedUrls = []; +function getContributionPortalUrl() { return 'https://apikey.qzz.io'; } +function openExternalUrl(url) { openedUrls.push(url); } ${bundle} return { - buildCloudflareTempEmailUsageGuideModalConfig, + openedUrls, + openCloudflareTempEmailUsageGuidePage, }; `)(); - const modalConfig = api.buildCloudflareTempEmailUsageGuideModalConfig(); - assert.equal(typeof modalConfig.title, 'string'); - assert.equal(typeof modalConfig.messageHtml, 'string'); - assert.equal(typeof modalConfig.alert?.text, 'string'); - assert.equal(modalConfig.title.length > 0, true); - assert.equal(modalConfig.messageHtml.length > 0, true); - assert.equal(modalConfig.alert.text.length > 0, true); - assert.equal(modalConfig.messageHtml.includes(' { - const bundle = extractFunction('buildCloudflareTempEmailUsageGuideModalConfig'); +test('openCloudflareTempEmailUsageGuidePage skips opening when the contribution portal URL is empty', () => { + const bundle = extractFunction('openCloudflareTempEmailUsageGuidePage'); const api = new Function(` -const selectMailProvider = { value: 'cloudflare-temp-email' }; -const selectEmailGenerator = { value: 'duck' }; -const CLOUDFLARE_TEMP_EMAIL_BUILD_TUTORIAL_URL = 'https://linux.do/t/topic/316819'; -const CLOUDFLARE_TEMP_EMAIL_RANDOM_SUBDOMAIN_ISSUE_URL = 'https://github.com/dreamhunter2333/cloudflare_temp_email/issues/942'; -function getSelectedEmailGenerator() { return String(selectEmailGenerator.value || '').trim().toLowerCase(); } +const openedUrls = []; +function getContributionPortalUrl() { return ''; } +function openExternalUrl(url) { openedUrls.push(url); } ${bundle} return { - buildCloudflareTempEmailUsageGuideModalConfig, + openedUrls, + openCloudflareTempEmailUsageGuidePage, }; `)(); - const providerConfig = api.buildCloudflareTempEmailUsageGuideModalConfig(); - - const generatorApi = new Function(` -const selectMailProvider = { value: '163' }; -const selectEmailGenerator = { value: 'cloudflare-temp-email' }; -const CLOUDFLARE_TEMP_EMAIL_BUILD_TUTORIAL_URL = 'https://linux.do/t/topic/316819'; -const CLOUDFLARE_TEMP_EMAIL_RANDOM_SUBDOMAIN_ISSUE_URL = 'https://github.com/dreamhunter2333/cloudflare_temp_email/issues/942'; -function getSelectedEmailGenerator() { return String(selectEmailGenerator.value || '').trim().toLowerCase(); } -${bundle} -return { - buildCloudflareTempEmailUsageGuideModalConfig, -}; - `)(); - - const generatorConfig = generatorApi.buildCloudflareTempEmailUsageGuideModalConfig(); - assert.equal(typeof providerConfig.alert?.text, 'string'); - assert.equal(typeof providerConfig.messageHtml, 'string'); - assert.equal(providerConfig.alert.text.length > 0, true); - assert.equal(providerConfig.messageHtml.length > 0, true); - assert.notEqual(providerConfig.alert.text, generatorConfig.alert.text); + api.openCloudflareTempEmailUsageGuidePage(); + assert.deepEqual(api.openedUrls, []); }); test('openCloudflareTempEmailRepositoryPage opens the upstream repository', () => {