feat(cloudflare): 支持 API Token 连接验证并发布 v1.6.7
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "fonu-web",
|
||||
"version": "1.6.6",
|
||||
"version": "1.6.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "fonu-web",
|
||||
"version": "1.6.6",
|
||||
"version": "1.6.7",
|
||||
"dependencies": {
|
||||
"@codemirror/commands": "^6.11.1",
|
||||
"@codemirror/lang-javascript": "^6.2.5",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "fonu-web",
|
||||
"private": true,
|
||||
"version": "1.6.6",
|
||||
"version": "1.6.7",
|
||||
"packageManager": "npm@10.9.4",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -512,9 +512,9 @@ export const api = {
|
||||
getCfSettings: () => request<CfAppSettings>('/api/cloudflare/settings'),
|
||||
saveCfSettings: (payload: CfAppSettingsInput) =>
|
||||
request<CfAppSettings>('/api/cloudflare/settings', { method: 'PUT', body: JSON.stringify(payload) }),
|
||||
testCfToken: (token: string) =>
|
||||
testCfToken: (token: string, kind: 'tunnel' | 'api') =>
|
||||
request<{ ok: boolean; message: string }>('/api/cloudflare/settings/test', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ token }),
|
||||
body: JSON.stringify({ token, kind }),
|
||||
}, 60_000),
|
||||
}
|
||||
|
||||
@@ -1102,12 +1102,15 @@ export interface CfTunnelPayload {
|
||||
export interface CfAppSettings {
|
||||
default_token_configured: boolean
|
||||
default_token_masked: string
|
||||
api_token_configured: boolean
|
||||
api_token_masked: string
|
||||
mirror: string
|
||||
network: CfNetworkSettings
|
||||
}
|
||||
|
||||
export interface CfAppSettingsInput {
|
||||
token: string
|
||||
api_token: string
|
||||
mirror: string
|
||||
network: CfNetworkSettings
|
||||
}
|
||||
|
||||
@@ -124,12 +124,20 @@
|
||||
|
||||
<n-divider title-placement="left">Token 配置</n-divider>
|
||||
<n-form label-placement="top">
|
||||
<n-form-item label="默认 Token">
|
||||
<n-form-item label="隧道 Token(Tunnel Token)">
|
||||
<n-input
|
||||
v-model:value="settingsForm.token"
|
||||
type="password"
|
||||
show-password-on="click"
|
||||
:placeholder="appSettings.default_token_configured ? `已配置 ${appSettings.default_token_masked},留空保留` : '粘贴 Cloudflare 隧道 token'"
|
||||
:placeholder="appSettings.default_token_configured ? `已配置 ${appSettings.default_token_masked},留空保留` : '粘贴 Cloudflare 隧道 token(eyJ...)'"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="API Token(可选,用于连接验证)">
|
||||
<n-input
|
||||
v-model:value="settingsForm.api_token"
|
||||
type="password"
|
||||
show-password-on="click"
|
||||
:placeholder="appSettings.api_token_configured ? `已配置 ${appSettings.api_token_masked},留空保留` : 'cfat_...'"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
@@ -140,7 +148,7 @@
|
||||
<n-alert v-if="tokenTestResult" :type="tokenTestOk ? 'success' : 'error'" :bordered="false" class="cf-mode-alert">
|
||||
{{ tokenTestResult }}
|
||||
</n-alert>
|
||||
<p class="cf-hint">保存后,新建隧道时可以留空 token,直接使用这里的默认值。</p>
|
||||
<p class="cf-hint">隧道 Token 用于 cloudflared 运行;API Token 用于验证 Cloudflare 账号连接(格式 cfat_...)。测试连接优先使用 API Token。</p>
|
||||
|
||||
<n-divider title-placement="left">默认网络设置</n-divider>
|
||||
<n-form label-placement="top">
|
||||
@@ -188,10 +196,12 @@ const tokenTestOk = ref(false)
|
||||
const appSettings = ref<CfAppSettings>({
|
||||
default_token_configured: false,
|
||||
default_token_masked: '',
|
||||
api_token_configured: false,
|
||||
api_token_masked: '',
|
||||
mirror: 'official',
|
||||
network: emptyNetwork(),
|
||||
})
|
||||
const settingsForm = ref<CfAppSettingsInput>({ token: '', mirror: 'official', network: emptyNetwork() })
|
||||
const settingsForm = ref<CfAppSettingsInput>({ token: '', api_token: '', mirror: 'official', network: emptyNetwork() })
|
||||
const editorVisible = ref(false)
|
||||
const detailVisible = ref(false)
|
||||
const editing = ref<CfTunnel | null>(null)
|
||||
@@ -409,7 +419,7 @@ async function loadAppSettings() {
|
||||
try {
|
||||
const result = await api.getCfSettings()
|
||||
appSettings.value = result
|
||||
settingsForm.value = { token: '', mirror: result.mirror || 'official', network: { ...result.network } }
|
||||
settingsForm.value = { token: '', api_token: '', mirror: result.mirror || 'official', network: { ...result.network } }
|
||||
} catch (error) {
|
||||
message.error(error instanceof Error ? error.message : '读取应用配置失败')
|
||||
} finally {
|
||||
@@ -420,8 +430,13 @@ async function loadAppSettings() {
|
||||
async function testToken() {
|
||||
tokenTesting.value = true
|
||||
tokenTestResult.value = ''
|
||||
const apiToken = (settingsForm.value.api_token || '').trim()
|
||||
const useAPI = apiToken !== '' || appSettings.value.api_token_configured
|
||||
try {
|
||||
const result = await api.testCfToken(settingsForm.value.token)
|
||||
const result = await api.testCfToken(
|
||||
useAPI ? apiToken : (settingsForm.value.token || ''),
|
||||
useAPI ? 'api' : 'tunnel',
|
||||
)
|
||||
tokenTestOk.value = true
|
||||
tokenTestResult.value = result.message || '连接成功'
|
||||
} catch (error) {
|
||||
@@ -437,7 +452,7 @@ async function saveSettings() {
|
||||
try {
|
||||
const result = await api.saveCfSettings(settingsForm.value)
|
||||
appSettings.value = result
|
||||
settingsForm.value = { token: '', mirror: result.mirror, network: { ...result.network } }
|
||||
settingsForm.value = { token: '', api_token: '', mirror: result.mirror, network: { ...result.network } }
|
||||
message.success('应用配置已保存')
|
||||
} catch (error) {
|
||||
message.error(error instanceof Error ? error.message : '保存应用配置失败')
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<n-alert type="success" :bordered="false" class="example-alert" title="v1.6.6 示例页面验证标识已生效">
|
||||
<n-alert type="success" :bordered="false" class="example-alert" title="v1.6.7 示例页面验证标识已生效">
|
||||
当前页面由 v{{ version }} 提供,验证标识为 <span class="mono">{{ verificationMarker }}</span>。
|
||||
如果你是在升级后首次看到这行内容,说明前端构建、镜像重建和服务重启均已成功。
|
||||
</n-alert>
|
||||
@@ -19,7 +19,7 @@
|
||||
<strong class="example-proof__value">{{ verificationRound }}</strong>
|
||||
</div>
|
||||
<div class="example-proof__hint">
|
||||
看到这个新区块,说明前端资源已经从旧版本切换到 v1.6.6。
|
||||
看到这个新区块,说明前端资源已经从旧版本切换到 v1.6.7。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,16 +33,16 @@
|
||||
<StatCard label="本次验证标识" :value="verificationMarker" sub="用于区分升级前后的前端资源" tone="blue" value-small>
|
||||
<template #icon><n-icon :component="FlashOutline" /></template>
|
||||
</StatCard>
|
||||
<StatCard label="页面状态" value="已更新" sub="v1.6.6 前端资源已加载" tone="teal">
|
||||
<StatCard label="页面状态" value="已更新" sub="v1.6.7 前端资源已加载" tone="teal">
|
||||
<template #icon><n-icon :component="CheckmarkCircleOutline" /></template>
|
||||
</StatCard>
|
||||
</div>
|
||||
|
||||
<FonuCard title="本次示例页变化" subtitle="用于确认升级后的页面内容确实发生变化">
|
||||
<ul class="example-changes">
|
||||
<li>页面版本提示更新为 v1.6.6。</li>
|
||||
<li>「本次升级验证」区块和页面状态同步更新为 v1.6.6。</li>
|
||||
<li>验证标识更新为 <span class="mono">v1.6.6-example-page</span>。</li>
|
||||
<li>页面版本提示更新为 v1.6.7。</li>
|
||||
<li>「本次升级验证」区块和页面状态同步更新为 v1.6.7。</li>
|
||||
<li>验证标识更新为 <span class="mono">v1.6.7-example-page</span>。</li>
|
||||
</ul>
|
||||
</FonuCard>
|
||||
|
||||
@@ -87,8 +87,8 @@ const message = useMessage()
|
||||
const version = ref(__APP_VERSION__)
|
||||
const checkedAt = ref('')
|
||||
const refreshing = ref(false)
|
||||
const verificationRound = 'v1.6.6'
|
||||
const verificationMarker = 'v1.6.6-example-page'
|
||||
const verificationRound = 'v1.6.7'
|
||||
const verificationMarker = 'v1.6.7-example-page'
|
||||
|
||||
async function refreshVersion() {
|
||||
refreshing.value = true
|
||||
|
||||
Reference in New Issue
Block a user