From 4f6966d7b3979809da9238498bf403ced840d20b Mon Sep 17 00:00:00 2001 From: IanShaw027 Date: Tue, 21 Apr 2026 00:05:42 +0800 Subject: [PATCH] frontend: route wechat oauth entry by public settings --- frontend/src/api/auth.ts | 55 ++++++ .../components/auth/WechatOAuthSection.vue | 62 ++++++- .../auth/__tests__/WechatOAuthSection.spec.ts | 170 ++++++++++++++++-- 3 files changed, 261 insertions(+), 26 deletions(-) diff --git a/frontend/src/api/auth.ts b/frontend/src/api/auth.ts index 6a2feb87..6c877d76 100644 --- a/frontend/src/api/auth.ts +++ b/frontend/src/api/auth.ts @@ -349,6 +349,61 @@ export async function getPublicSettings(): Promise { return data } +export type WeChatOAuthMode = 'open' | 'mp' +export type WeChatOAuthUnavailableReason = + | 'not_configured' + | 'external_browser_required' + | 'wechat_browser_required' + +export interface ResolvedWeChatOAuthStart { + mode: WeChatOAuthMode | null + openEnabled: boolean + mpEnabled: boolean + isWeChatBrowser: boolean + unavailableReason: WeChatOAuthUnavailableReason | null +} + +type WeChatOAuthPublicSettings = { + wechat_oauth_enabled?: boolean + wechat_oauth_open_enabled?: boolean + wechat_oauth_mp_enabled?: boolean +} + +export function resolveWeChatOAuthStart( + settings: WeChatOAuthPublicSettings | null | undefined, + userAgent?: string +): ResolvedWeChatOAuthStart { + const normalizedUserAgent = (userAgent + ?? (typeof navigator !== 'undefined' ? navigator.userAgent : '') + ?? '').trim() + const isWeChatBrowser = /MicroMessenger/i.test(normalizedUserAgent) + const legacyEnabled = settings?.wechat_oauth_enabled ?? false + const openEnabled = typeof settings?.wechat_oauth_open_enabled === 'boolean' + ? settings.wechat_oauth_open_enabled + : legacyEnabled + const mpEnabled = typeof settings?.wechat_oauth_mp_enabled === 'boolean' + ? settings.wechat_oauth_mp_enabled + : legacyEnabled + + if (isWeChatBrowser) { + if (mpEnabled) { + return { mode: 'mp', openEnabled, mpEnabled, isWeChatBrowser, unavailableReason: null } + } + if (openEnabled) { + return { mode: null, openEnabled, mpEnabled, isWeChatBrowser, unavailableReason: 'external_browser_required' } + } + return { mode: null, openEnabled, mpEnabled, isWeChatBrowser, unavailableReason: 'not_configured' } + } + + if (openEnabled) { + return { mode: 'open', openEnabled, mpEnabled, isWeChatBrowser, unavailableReason: null } + } + if (mpEnabled) { + return { mode: null, openEnabled, mpEnabled, isWeChatBrowser, unavailableReason: 'wechat_browser_required' } + } + return { mode: null, openEnabled, mpEnabled, isWeChatBrowser, unavailableReason: 'not_configured' } +} + /** * Send verification code to email * @param request - Email and optional Turnstile token diff --git a/frontend/src/components/auth/WechatOAuthSection.vue b/frontend/src/components/auth/WechatOAuthSection.vue index 94e20222..01bbd180 100644 --- a/frontend/src/components/auth/WechatOAuthSection.vue +++ b/frontend/src/components/auth/WechatOAuthSection.vue @@ -1,6 +1,6 @@