merge: 合并 upstream/main 并解决冲突
解决了以下文件的冲突: - backend/internal/handler/admin/setting_handler.go - 采用 upstream 的字段对齐风格和 *Configured 字段名 - 添加 EnableIdentityPatch 和 IdentityPatchPrompt 字段 - backend/internal/handler/gateway_handler.go - 采用 upstream 的 billingErrorDetails 错误处理方式 - frontend/src/api/admin/settings.ts - 采用 upstream 的 *_configured 字段名 - 添加 enable_identity_patch 和 identity_patch_prompt 字段 - frontend/src/views/admin/SettingsView.vue - 合并 turnstile_secret_key_configured 字段 - 保留 enable_identity_patch 和 identity_patch_prompt 字段
This commit is contained in:
37
frontend/src/utils/url.ts
Normal file
37
frontend/src/utils/url.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 验证并规范化 URL
|
||||
* 默认只接受绝对 URL(以 http:// 或 https:// 开头),可按需允许相对路径
|
||||
* @param value 用户输入的 URL
|
||||
* @returns 规范化后的 URL,如果无效则返回空字符串
|
||||
*/
|
||||
type SanitizeOptions = {
|
||||
allowRelative?: boolean
|
||||
}
|
||||
|
||||
export function sanitizeUrl(value: string, options: SanitizeOptions = {}): string {
|
||||
const trimmed = value.trim()
|
||||
if (!trimmed) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (options.allowRelative && trimmed.startsWith('/') && !trimmed.startsWith('//')) {
|
||||
return trimmed
|
||||
}
|
||||
|
||||
// 只接受绝对 URL,不使用 base URL 来避免相对路径被解析为当前域名
|
||||
// 检查是否以 http:// 或 https:// 开头
|
||||
if (!trimmed.match(/^https?:\/\//i)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = new URL(trimmed)
|
||||
const protocol = parsed.protocol.toLowerCase()
|
||||
if (protocol !== 'http:' && protocol !== 'https:') {
|
||||
return ''
|
||||
}
|
||||
return parsed.toString()
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user