feat(settings): support per-channel WeChat OAuth and persist payment options
This commit is contained in:
@@ -43,6 +43,15 @@ func scopesContainOpenID(scopes string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func firstNonEmpty(values ...string) string {
|
||||||
|
for _, value := range values {
|
||||||
|
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
||||||
|
return trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// SettingHandler 系统设置处理器
|
// SettingHandler 系统设置处理器
|
||||||
type SettingHandler struct {
|
type SettingHandler struct {
|
||||||
settingService *service.SettingService
|
settingService *service.SettingService
|
||||||
@@ -125,8 +134,15 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
|
|||||||
WeChatConnectEnabled: settings.WeChatConnectEnabled,
|
WeChatConnectEnabled: settings.WeChatConnectEnabled,
|
||||||
WeChatConnectAppID: settings.WeChatConnectAppID,
|
WeChatConnectAppID: settings.WeChatConnectAppID,
|
||||||
WeChatConnectAppSecretConfigured: settings.WeChatConnectAppSecretConfigured,
|
WeChatConnectAppSecretConfigured: settings.WeChatConnectAppSecretConfigured,
|
||||||
|
WeChatConnectOpenAppID: settings.WeChatConnectOpenAppID,
|
||||||
|
WeChatConnectOpenAppSecretConfigured: settings.WeChatConnectOpenAppSecretConfigured,
|
||||||
|
WeChatConnectMPAppID: settings.WeChatConnectMPAppID,
|
||||||
|
WeChatConnectMPAppSecretConfigured: settings.WeChatConnectMPAppSecretConfigured,
|
||||||
|
WeChatConnectMobileAppID: settings.WeChatConnectMobileAppID,
|
||||||
|
WeChatConnectMobileAppSecretConfigured: settings.WeChatConnectMobileAppSecretConfigured,
|
||||||
WeChatConnectOpenEnabled: settings.WeChatConnectOpenEnabled,
|
WeChatConnectOpenEnabled: settings.WeChatConnectOpenEnabled,
|
||||||
WeChatConnectMPEnabled: settings.WeChatConnectMPEnabled,
|
WeChatConnectMPEnabled: settings.WeChatConnectMPEnabled,
|
||||||
|
WeChatConnectMobileEnabled: settings.WeChatConnectMobileEnabled,
|
||||||
WeChatConnectMode: settings.WeChatConnectMode,
|
WeChatConnectMode: settings.WeChatConnectMode,
|
||||||
WeChatConnectScopes: settings.WeChatConnectScopes,
|
WeChatConnectScopes: settings.WeChatConnectScopes,
|
||||||
WeChatConnectRedirectURL: settings.WeChatConnectRedirectURL,
|
WeChatConnectRedirectURL: settings.WeChatConnectRedirectURL,
|
||||||
@@ -259,8 +275,15 @@ type UpdateSettingsRequest struct {
|
|||||||
WeChatConnectEnabled bool `json:"wechat_connect_enabled"`
|
WeChatConnectEnabled bool `json:"wechat_connect_enabled"`
|
||||||
WeChatConnectAppID string `json:"wechat_connect_app_id"`
|
WeChatConnectAppID string `json:"wechat_connect_app_id"`
|
||||||
WeChatConnectAppSecret string `json:"wechat_connect_app_secret"`
|
WeChatConnectAppSecret string `json:"wechat_connect_app_secret"`
|
||||||
|
WeChatConnectOpenAppID string `json:"wechat_connect_open_app_id"`
|
||||||
|
WeChatConnectOpenAppSecret string `json:"wechat_connect_open_app_secret"`
|
||||||
|
WeChatConnectMPAppID string `json:"wechat_connect_mp_app_id"`
|
||||||
|
WeChatConnectMPAppSecret string `json:"wechat_connect_mp_app_secret"`
|
||||||
|
WeChatConnectMobileAppID string `json:"wechat_connect_mobile_app_id"`
|
||||||
|
WeChatConnectMobileAppSecret string `json:"wechat_connect_mobile_app_secret"`
|
||||||
WeChatConnectOpenEnabled bool `json:"wechat_connect_open_enabled"`
|
WeChatConnectOpenEnabled bool `json:"wechat_connect_open_enabled"`
|
||||||
WeChatConnectMPEnabled bool `json:"wechat_connect_mp_enabled"`
|
WeChatConnectMPEnabled bool `json:"wechat_connect_mp_enabled"`
|
||||||
|
WeChatConnectMobileEnabled bool `json:"wechat_connect_mobile_enabled"`
|
||||||
WeChatConnectMode string `json:"wechat_connect_mode"`
|
WeChatConnectMode string `json:"wechat_connect_mode"`
|
||||||
WeChatConnectScopes string `json:"wechat_connect_scopes"`
|
WeChatConnectScopes string `json:"wechat_connect_scopes"`
|
||||||
WeChatConnectRedirectURL string `json:"wechat_connect_redirect_url"`
|
WeChatConnectRedirectURL string `json:"wechat_connect_redirect_url"`
|
||||||
@@ -532,34 +555,35 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
if req.WeChatConnectEnabled {
|
if req.WeChatConnectEnabled {
|
||||||
req.WeChatConnectAppID = strings.TrimSpace(req.WeChatConnectAppID)
|
req.WeChatConnectAppID = strings.TrimSpace(req.WeChatConnectAppID)
|
||||||
req.WeChatConnectAppSecret = strings.TrimSpace(req.WeChatConnectAppSecret)
|
req.WeChatConnectAppSecret = strings.TrimSpace(req.WeChatConnectAppSecret)
|
||||||
|
req.WeChatConnectOpenAppID = strings.TrimSpace(req.WeChatConnectOpenAppID)
|
||||||
|
req.WeChatConnectOpenAppSecret = strings.TrimSpace(req.WeChatConnectOpenAppSecret)
|
||||||
|
req.WeChatConnectMPAppID = strings.TrimSpace(req.WeChatConnectMPAppID)
|
||||||
|
req.WeChatConnectMPAppSecret = strings.TrimSpace(req.WeChatConnectMPAppSecret)
|
||||||
|
req.WeChatConnectMobileAppID = strings.TrimSpace(req.WeChatConnectMobileAppID)
|
||||||
|
req.WeChatConnectMobileAppSecret = strings.TrimSpace(req.WeChatConnectMobileAppSecret)
|
||||||
req.WeChatConnectMode = strings.ToLower(strings.TrimSpace(req.WeChatConnectMode))
|
req.WeChatConnectMode = strings.ToLower(strings.TrimSpace(req.WeChatConnectMode))
|
||||||
req.WeChatConnectScopes = strings.TrimSpace(req.WeChatConnectScopes)
|
req.WeChatConnectScopes = strings.TrimSpace(req.WeChatConnectScopes)
|
||||||
req.WeChatConnectRedirectURL = strings.TrimSpace(req.WeChatConnectRedirectURL)
|
req.WeChatConnectRedirectURL = strings.TrimSpace(req.WeChatConnectRedirectURL)
|
||||||
req.WeChatConnectFrontendRedirectURL = strings.TrimSpace(req.WeChatConnectFrontendRedirectURL)
|
req.WeChatConnectFrontendRedirectURL = strings.TrimSpace(req.WeChatConnectFrontendRedirectURL)
|
||||||
|
|
||||||
if req.WeChatConnectAppID == "" {
|
if req.WeChatConnectMPEnabled && req.WeChatConnectMobileEnabled {
|
||||||
response.BadRequest(c, "WeChat App ID is required when enabled")
|
response.BadRequest(c, "WeChat Official Account and Mobile App cannot be enabled at the same time")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if req.WeChatConnectAppSecret == "" {
|
|
||||||
if previousSettings.WeChatConnectAppSecret == "" {
|
|
||||||
response.BadRequest(c, "WeChat App Secret is required when enabled")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req.WeChatConnectAppSecret = previousSettings.WeChatConnectAppSecret
|
|
||||||
}
|
|
||||||
if req.WeChatConnectMode != "" {
|
if req.WeChatConnectMode != "" {
|
||||||
switch req.WeChatConnectMode {
|
switch req.WeChatConnectMode {
|
||||||
case "open", "mp":
|
case "open", "mp", "mobile":
|
||||||
default:
|
default:
|
||||||
response.BadRequest(c, "WeChat mode must be open or mp")
|
response.BadRequest(c, "WeChat mode must be open, mp, or mobile")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !req.WeChatConnectOpenEnabled && !req.WeChatConnectMPEnabled {
|
if !req.WeChatConnectOpenEnabled && !req.WeChatConnectMPEnabled && !req.WeChatConnectMobileEnabled {
|
||||||
switch req.WeChatConnectMode {
|
switch req.WeChatConnectMode {
|
||||||
case "mp":
|
case "mp":
|
||||||
req.WeChatConnectMPEnabled = true
|
req.WeChatConnectMPEnabled = true
|
||||||
|
case "mobile":
|
||||||
|
req.WeChatConnectMobileEnabled = true
|
||||||
default:
|
default:
|
||||||
req.WeChatConnectOpenEnabled = true
|
req.WeChatConnectOpenEnabled = true
|
||||||
}
|
}
|
||||||
@@ -567,10 +591,61 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
if req.WeChatConnectMode == "" {
|
if req.WeChatConnectMode == "" {
|
||||||
if req.WeChatConnectMPEnabled {
|
if req.WeChatConnectMPEnabled {
|
||||||
req.WeChatConnectMode = "mp"
|
req.WeChatConnectMode = "mp"
|
||||||
|
} else if req.WeChatConnectMobileEnabled {
|
||||||
|
req.WeChatConnectMode = "mobile"
|
||||||
} else {
|
} else {
|
||||||
req.WeChatConnectMode = "open"
|
req.WeChatConnectMode = "open"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.WeChatConnectOpenAppID = strings.TrimSpace(firstNonEmpty(req.WeChatConnectOpenAppID, req.WeChatConnectAppID))
|
||||||
|
req.WeChatConnectMPAppID = strings.TrimSpace(firstNonEmpty(req.WeChatConnectMPAppID, req.WeChatConnectAppID))
|
||||||
|
req.WeChatConnectMobileAppID = strings.TrimSpace(firstNonEmpty(req.WeChatConnectMobileAppID, req.WeChatConnectAppID))
|
||||||
|
|
||||||
|
if req.WeChatConnectOpenAppSecret == "" {
|
||||||
|
req.WeChatConnectOpenAppSecret = strings.TrimSpace(firstNonEmpty(previousSettings.WeChatConnectOpenAppSecret, previousSettings.WeChatConnectAppSecret, req.WeChatConnectAppSecret))
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMPAppSecret == "" {
|
||||||
|
req.WeChatConnectMPAppSecret = strings.TrimSpace(firstNonEmpty(previousSettings.WeChatConnectMPAppSecret, previousSettings.WeChatConnectAppSecret, req.WeChatConnectAppSecret))
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMobileAppSecret == "" {
|
||||||
|
req.WeChatConnectMobileAppSecret = strings.TrimSpace(firstNonEmpty(previousSettings.WeChatConnectMobileAppSecret, previousSettings.WeChatConnectAppSecret, req.WeChatConnectAppSecret))
|
||||||
|
}
|
||||||
|
if req.WeChatConnectAppSecret == "" {
|
||||||
|
req.WeChatConnectAppSecret = strings.TrimSpace(firstNonEmpty(req.WeChatConnectOpenAppSecret, req.WeChatConnectMPAppSecret, req.WeChatConnectMobileAppSecret, previousSettings.WeChatConnectAppSecret))
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.WeChatConnectOpenEnabled {
|
||||||
|
if req.WeChatConnectOpenAppID == "" {
|
||||||
|
response.BadRequest(c, "WeChat PC App ID is required when enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.WeChatConnectOpenAppSecret == "" {
|
||||||
|
response.BadRequest(c, "WeChat PC App Secret is required when enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMPEnabled {
|
||||||
|
if req.WeChatConnectMPAppID == "" {
|
||||||
|
response.BadRequest(c, "WeChat Official Account App ID is required when enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMPAppSecret == "" {
|
||||||
|
response.BadRequest(c, "WeChat Official Account App Secret is required when enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMobileEnabled {
|
||||||
|
if req.WeChatConnectMobileAppID == "" {
|
||||||
|
response.BadRequest(c, "WeChat Mobile App ID is required when enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMobileAppSecret == "" {
|
||||||
|
response.BadRequest(c, "WeChat Mobile App Secret is required when enabled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if req.WeChatConnectScopes == "" {
|
if req.WeChatConnectScopes == "" {
|
||||||
if req.WeChatConnectMPEnabled {
|
if req.WeChatConnectMPEnabled {
|
||||||
req.WeChatConnectScopes = service.DefaultWeChatConnectScopesForMode("mp")
|
req.WeChatConnectScopes = service.DefaultWeChatConnectScopesForMode("mp")
|
||||||
@@ -946,8 +1021,15 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
WeChatConnectEnabled: req.WeChatConnectEnabled,
|
WeChatConnectEnabled: req.WeChatConnectEnabled,
|
||||||
WeChatConnectAppID: req.WeChatConnectAppID,
|
WeChatConnectAppID: req.WeChatConnectAppID,
|
||||||
WeChatConnectAppSecret: req.WeChatConnectAppSecret,
|
WeChatConnectAppSecret: req.WeChatConnectAppSecret,
|
||||||
|
WeChatConnectOpenAppID: req.WeChatConnectOpenAppID,
|
||||||
|
WeChatConnectOpenAppSecret: req.WeChatConnectOpenAppSecret,
|
||||||
|
WeChatConnectMPAppID: req.WeChatConnectMPAppID,
|
||||||
|
WeChatConnectMPAppSecret: req.WeChatConnectMPAppSecret,
|
||||||
|
WeChatConnectMobileAppID: req.WeChatConnectMobileAppID,
|
||||||
|
WeChatConnectMobileAppSecret: req.WeChatConnectMobileAppSecret,
|
||||||
WeChatConnectOpenEnabled: req.WeChatConnectOpenEnabled,
|
WeChatConnectOpenEnabled: req.WeChatConnectOpenEnabled,
|
||||||
WeChatConnectMPEnabled: req.WeChatConnectMPEnabled,
|
WeChatConnectMPEnabled: req.WeChatConnectMPEnabled,
|
||||||
|
WeChatConnectMobileEnabled: req.WeChatConnectMobileEnabled,
|
||||||
WeChatConnectMode: req.WeChatConnectMode,
|
WeChatConnectMode: req.WeChatConnectMode,
|
||||||
WeChatConnectScopes: req.WeChatConnectScopes,
|
WeChatConnectScopes: req.WeChatConnectScopes,
|
||||||
WeChatConnectRedirectURL: req.WeChatConnectRedirectURL,
|
WeChatConnectRedirectURL: req.WeChatConnectRedirectURL,
|
||||||
@@ -1234,8 +1316,15 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
WeChatConnectEnabled: updatedSettings.WeChatConnectEnabled,
|
WeChatConnectEnabled: updatedSettings.WeChatConnectEnabled,
|
||||||
WeChatConnectAppID: updatedSettings.WeChatConnectAppID,
|
WeChatConnectAppID: updatedSettings.WeChatConnectAppID,
|
||||||
WeChatConnectAppSecretConfigured: updatedSettings.WeChatConnectAppSecretConfigured,
|
WeChatConnectAppSecretConfigured: updatedSettings.WeChatConnectAppSecretConfigured,
|
||||||
|
WeChatConnectOpenAppID: updatedSettings.WeChatConnectOpenAppID,
|
||||||
|
WeChatConnectOpenAppSecretConfigured: updatedSettings.WeChatConnectOpenAppSecretConfigured,
|
||||||
|
WeChatConnectMPAppID: updatedSettings.WeChatConnectMPAppID,
|
||||||
|
WeChatConnectMPAppSecretConfigured: updatedSettings.WeChatConnectMPAppSecretConfigured,
|
||||||
|
WeChatConnectMobileAppID: updatedSettings.WeChatConnectMobileAppID,
|
||||||
|
WeChatConnectMobileAppSecretConfigured: updatedSettings.WeChatConnectMobileAppSecretConfigured,
|
||||||
WeChatConnectOpenEnabled: updatedSettings.WeChatConnectOpenEnabled,
|
WeChatConnectOpenEnabled: updatedSettings.WeChatConnectOpenEnabled,
|
||||||
WeChatConnectMPEnabled: updatedSettings.WeChatConnectMPEnabled,
|
WeChatConnectMPEnabled: updatedSettings.WeChatConnectMPEnabled,
|
||||||
|
WeChatConnectMobileEnabled: updatedSettings.WeChatConnectMobileEnabled,
|
||||||
WeChatConnectMode: updatedSettings.WeChatConnectMode,
|
WeChatConnectMode: updatedSettings.WeChatConnectMode,
|
||||||
WeChatConnectScopes: updatedSettings.WeChatConnectScopes,
|
WeChatConnectScopes: updatedSettings.WeChatConnectScopes,
|
||||||
WeChatConnectRedirectURL: updatedSettings.WeChatConnectRedirectURL,
|
WeChatConnectRedirectURL: updatedSettings.WeChatConnectRedirectURL,
|
||||||
@@ -1442,12 +1531,33 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings,
|
|||||||
if req.WeChatConnectAppSecret != "" {
|
if req.WeChatConnectAppSecret != "" {
|
||||||
changed = append(changed, "wechat_connect_app_secret")
|
changed = append(changed, "wechat_connect_app_secret")
|
||||||
}
|
}
|
||||||
|
if before.WeChatConnectOpenAppID != after.WeChatConnectOpenAppID {
|
||||||
|
changed = append(changed, "wechat_connect_open_app_id")
|
||||||
|
}
|
||||||
|
if req.WeChatConnectOpenAppSecret != "" {
|
||||||
|
changed = append(changed, "wechat_connect_open_app_secret")
|
||||||
|
}
|
||||||
|
if before.WeChatConnectMPAppID != after.WeChatConnectMPAppID {
|
||||||
|
changed = append(changed, "wechat_connect_mp_app_id")
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMPAppSecret != "" {
|
||||||
|
changed = append(changed, "wechat_connect_mp_app_secret")
|
||||||
|
}
|
||||||
|
if before.WeChatConnectMobileAppID != after.WeChatConnectMobileAppID {
|
||||||
|
changed = append(changed, "wechat_connect_mobile_app_id")
|
||||||
|
}
|
||||||
|
if req.WeChatConnectMobileAppSecret != "" {
|
||||||
|
changed = append(changed, "wechat_connect_mobile_app_secret")
|
||||||
|
}
|
||||||
if before.WeChatConnectOpenEnabled != after.WeChatConnectOpenEnabled {
|
if before.WeChatConnectOpenEnabled != after.WeChatConnectOpenEnabled {
|
||||||
changed = append(changed, "wechat_connect_open_enabled")
|
changed = append(changed, "wechat_connect_open_enabled")
|
||||||
}
|
}
|
||||||
if before.WeChatConnectMPEnabled != after.WeChatConnectMPEnabled {
|
if before.WeChatConnectMPEnabled != after.WeChatConnectMPEnabled {
|
||||||
changed = append(changed, "wechat_connect_mp_enabled")
|
changed = append(changed, "wechat_connect_mp_enabled")
|
||||||
}
|
}
|
||||||
|
if before.WeChatConnectMobileEnabled != after.WeChatConnectMobileEnabled {
|
||||||
|
changed = append(changed, "wechat_connect_mobile_enabled")
|
||||||
|
}
|
||||||
if before.WeChatConnectMode != after.WeChatConnectMode {
|
if before.WeChatConnectMode != after.WeChatConnectMode {
|
||||||
changed = append(changed, "wechat_connect_mode")
|
changed = append(changed, "wechat_connect_mode")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -753,9 +753,15 @@ func (h *AuthHandler) ensureWeChatBindOwnership(
|
|||||||
}
|
}
|
||||||
for _, identity := range identities {
|
for _, identity := range identities {
|
||||||
if identity != nil && identity.UserID != userID {
|
if identity != nil && identity.UserID != userID {
|
||||||
|
activeOwner, lookupErr := findActiveUserByID(ctx, client, identity.UserID)
|
||||||
|
if lookupErr != nil {
|
||||||
|
return lookupErr
|
||||||
|
}
|
||||||
|
if activeOwner != nil {
|
||||||
return infraerrors.Conflict("AUTH_IDENTITY_OWNERSHIP_CONFLICT", "auth identity already belongs to another user")
|
return infraerrors.Conflict("AUTH_IDENTITY_OWNERSHIP_CONFLICT", "auth identity already belongs to another user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
channelSubject = strings.TrimSpace(channelSubject)
|
channelSubject = strings.TrimSpace(channelSubject)
|
||||||
channelAppID := strings.TrimSpace(cfg.appID)
|
channelAppID := strings.TrimSpace(cfg.appID)
|
||||||
@@ -778,9 +784,15 @@ func (h *AuthHandler) ensureWeChatBindOwnership(
|
|||||||
}
|
}
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
if channel != nil && channel.Edges.Identity != nil && channel.Edges.Identity.UserID != userID {
|
if channel != nil && channel.Edges.Identity != nil && channel.Edges.Identity.UserID != userID {
|
||||||
|
activeOwner, lookupErr := findActiveUserByID(ctx, client, channel.Edges.Identity.UserID)
|
||||||
|
if lookupErr != nil {
|
||||||
|
return lookupErr
|
||||||
|
}
|
||||||
|
if activeOwner != nil {
|
||||||
return infraerrors.Conflict("AUTH_IDENTITY_CHANNEL_OWNERSHIP_CONFLICT", "auth identity channel already belongs to another user")
|
return infraerrors.Conflict("AUTH_IDENTITY_CHANNEL_OWNERSHIP_CONFLICT", "auth identity channel already belongs to another user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,8 +972,8 @@ func (h *AuthHandler) getWeChatOAuthConfig(ctx context.Context, rawMode string,
|
|||||||
|
|
||||||
cfg := wechatOAuthConfig{
|
cfg := wechatOAuthConfig{
|
||||||
mode: mode,
|
mode: mode,
|
||||||
appID: strings.TrimSpace(effective.AppID),
|
appID: strings.TrimSpace(effective.AppIDForMode(mode)),
|
||||||
appSecret: strings.TrimSpace(effective.AppSecret),
|
appSecret: strings.TrimSpace(effective.AppSecretForMode(mode)),
|
||||||
redirectURI: firstNonEmpty(strings.TrimSpace(effective.RedirectURL), resolveWeChatOAuthAbsoluteURL(apiBaseURL, c, "/api/v1/auth/oauth/wechat/callback")),
|
redirectURI: firstNonEmpty(strings.TrimSpace(effective.RedirectURL), resolveWeChatOAuthAbsoluteURL(apiBaseURL, c, "/api/v1/auth/oauth/wechat/callback")),
|
||||||
frontendCallback: firstNonEmpty(strings.TrimSpace(effective.FrontendRedirectURL), wechatOAuthDefaultFrontendCB),
|
frontendCallback: firstNonEmpty(strings.TrimSpace(effective.FrontendRedirectURL), wechatOAuthDefaultFrontendCB),
|
||||||
scope: effective.ScopeForMode(mode),
|
scope: effective.ScopeForMode(mode),
|
||||||
|
|||||||
@@ -54,8 +54,15 @@ type SystemSettings struct {
|
|||||||
WeChatConnectEnabled bool `json:"wechat_connect_enabled"`
|
WeChatConnectEnabled bool `json:"wechat_connect_enabled"`
|
||||||
WeChatConnectAppID string `json:"wechat_connect_app_id"`
|
WeChatConnectAppID string `json:"wechat_connect_app_id"`
|
||||||
WeChatConnectAppSecretConfigured bool `json:"wechat_connect_app_secret_configured"`
|
WeChatConnectAppSecretConfigured bool `json:"wechat_connect_app_secret_configured"`
|
||||||
|
WeChatConnectOpenAppID string `json:"wechat_connect_open_app_id"`
|
||||||
|
WeChatConnectOpenAppSecretConfigured bool `json:"wechat_connect_open_app_secret_configured"`
|
||||||
|
WeChatConnectMPAppID string `json:"wechat_connect_mp_app_id"`
|
||||||
|
WeChatConnectMPAppSecretConfigured bool `json:"wechat_connect_mp_app_secret_configured"`
|
||||||
|
WeChatConnectMobileAppID string `json:"wechat_connect_mobile_app_id"`
|
||||||
|
WeChatConnectMobileAppSecretConfigured bool `json:"wechat_connect_mobile_app_secret_configured"`
|
||||||
WeChatConnectOpenEnabled bool `json:"wechat_connect_open_enabled"`
|
WeChatConnectOpenEnabled bool `json:"wechat_connect_open_enabled"`
|
||||||
WeChatConnectMPEnabled bool `json:"wechat_connect_mp_enabled"`
|
WeChatConnectMPEnabled bool `json:"wechat_connect_mp_enabled"`
|
||||||
|
WeChatConnectMobileEnabled bool `json:"wechat_connect_mobile_enabled"`
|
||||||
WeChatConnectMode string `json:"wechat_connect_mode"`
|
WeChatConnectMode string `json:"wechat_connect_mode"`
|
||||||
WeChatConnectScopes string `json:"wechat_connect_scopes"`
|
WeChatConnectScopes string `json:"wechat_connect_scopes"`
|
||||||
WeChatConnectRedirectURL string `json:"wechat_connect_redirect_url"`
|
WeChatConnectRedirectURL string `json:"wechat_connect_redirect_url"`
|
||||||
@@ -212,6 +219,7 @@ type PublicSettings struct {
|
|||||||
WeChatOAuthEnabled bool `json:"wechat_oauth_enabled"`
|
WeChatOAuthEnabled bool `json:"wechat_oauth_enabled"`
|
||||||
WeChatOAuthOpenEnabled bool `json:"wechat_oauth_open_enabled"`
|
WeChatOAuthOpenEnabled bool `json:"wechat_oauth_open_enabled"`
|
||||||
WeChatOAuthMPEnabled bool `json:"wechat_oauth_mp_enabled"`
|
WeChatOAuthMPEnabled bool `json:"wechat_oauth_mp_enabled"`
|
||||||
|
WeChatOAuthMobileEnabled bool `json:"wechat_oauth_mobile_enabled"`
|
||||||
OIDCOAuthEnabled bool `json:"oidc_oauth_enabled"`
|
OIDCOAuthEnabled bool `json:"oidc_oauth_enabled"`
|
||||||
OIDCOAuthProviderName string `json:"oidc_oauth_provider_name"`
|
OIDCOAuthProviderName string `json:"oidc_oauth_provider_name"`
|
||||||
SoraClientEnabled bool `json:"sora_client_enabled"`
|
SoraClientEnabled bool `json:"sora_client_enabled"`
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ func (h *SettingHandler) GetPublicSettings(c *gin.Context) {
|
|||||||
WeChatOAuthEnabled: settings.WeChatOAuthEnabled,
|
WeChatOAuthEnabled: settings.WeChatOAuthEnabled,
|
||||||
WeChatOAuthOpenEnabled: settings.WeChatOAuthOpenEnabled,
|
WeChatOAuthOpenEnabled: settings.WeChatOAuthOpenEnabled,
|
||||||
WeChatOAuthMPEnabled: settings.WeChatOAuthMPEnabled,
|
WeChatOAuthMPEnabled: settings.WeChatOAuthMPEnabled,
|
||||||
|
WeChatOAuthMobileEnabled: settings.WeChatOAuthMobileEnabled,
|
||||||
OIDCOAuthEnabled: settings.OIDCOAuthEnabled,
|
OIDCOAuthEnabled: settings.OIDCOAuthEnabled,
|
||||||
OIDCOAuthProviderName: settings.OIDCOAuthProviderName,
|
OIDCOAuthProviderName: settings.OIDCOAuthProviderName,
|
||||||
BackendModeEnabled: settings.BackendModeEnabled,
|
BackendModeEnabled: settings.BackendModeEnabled,
|
||||||
|
|||||||
@@ -115,8 +115,15 @@ const (
|
|||||||
SettingKeyWeChatConnectEnabled = "wechat_connect_enabled"
|
SettingKeyWeChatConnectEnabled = "wechat_connect_enabled"
|
||||||
SettingKeyWeChatConnectAppID = "wechat_connect_app_id"
|
SettingKeyWeChatConnectAppID = "wechat_connect_app_id"
|
||||||
SettingKeyWeChatConnectAppSecret = "wechat_connect_app_secret"
|
SettingKeyWeChatConnectAppSecret = "wechat_connect_app_secret"
|
||||||
|
SettingKeyWeChatConnectOpenAppID = "wechat_connect_open_app_id"
|
||||||
|
SettingKeyWeChatConnectOpenAppSecret = "wechat_connect_open_app_secret"
|
||||||
|
SettingKeyWeChatConnectMPAppID = "wechat_connect_mp_app_id"
|
||||||
|
SettingKeyWeChatConnectMPAppSecret = "wechat_connect_mp_app_secret"
|
||||||
|
SettingKeyWeChatConnectMobileAppID = "wechat_connect_mobile_app_id"
|
||||||
|
SettingKeyWeChatConnectMobileAppSecret = "wechat_connect_mobile_app_secret"
|
||||||
SettingKeyWeChatConnectOpenEnabled = "wechat_connect_open_enabled"
|
SettingKeyWeChatConnectOpenEnabled = "wechat_connect_open_enabled"
|
||||||
SettingKeyWeChatConnectMPEnabled = "wechat_connect_mp_enabled"
|
SettingKeyWeChatConnectMPEnabled = "wechat_connect_mp_enabled"
|
||||||
|
SettingKeyWeChatConnectMobileEnabled = "wechat_connect_mobile_enabled"
|
||||||
SettingKeyWeChatConnectMode = "wechat_connect_mode"
|
SettingKeyWeChatConnectMode = "wechat_connect_mode"
|
||||||
SettingKeyWeChatConnectScopes = "wechat_connect_scopes"
|
SettingKeyWeChatConnectScopes = "wechat_connect_scopes"
|
||||||
SettingKeyWeChatConnectRedirectURL = "wechat_connect_redirect_url"
|
SettingKeyWeChatConnectRedirectURL = "wechat_connect_redirect_url"
|
||||||
|
|||||||
@@ -519,13 +519,15 @@ func (s *PaymentService) getWeChatPaymentOAuthCredential(ctx context.Context) (s
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
cfg, err := (&SettingService{settingRepo: s.configService.settingRepo}).GetWeChatConnectOAuthConfig(ctx)
|
cfg, err := (&SettingService{settingRepo: s.configService.settingRepo}).GetWeChatConnectOAuthConfig(ctx)
|
||||||
if err != nil || !cfg.SupportsMode("mp") || strings.TrimSpace(cfg.AppID) == "" || strings.TrimSpace(cfg.AppSecret) == "" {
|
appID := strings.TrimSpace(cfg.AppIDForMode("mp"))
|
||||||
|
appSecret := strings.TrimSpace(cfg.AppSecretForMode("mp"))
|
||||||
|
if err != nil || !cfg.SupportsMode("mp") || appID == "" || appSecret == "" {
|
||||||
return "", "", infraerrors.ServiceUnavailable(
|
return "", "", infraerrors.ServiceUnavailable(
|
||||||
"WECHAT_PAYMENT_MP_NOT_CONFIGURED",
|
"WECHAT_PAYMENT_MP_NOT_CONFIGURED",
|
||||||
"wechat in-app payment requires a complete WeChat MP OAuth credential",
|
"wechat in-app payment requires a complete WeChat MP OAuth credential",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(cfg.AppID), strings.TrimSpace(cfg.AppSecret), nil
|
return appID, appSecret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func classifyCreatePaymentError(req CreateOrderRequest, providerKey string, err error) error {
|
func classifyCreatePaymentError(req CreateOrderRequest, providerKey string, err error) error {
|
||||||
|
|||||||
@@ -181,14 +181,19 @@ func normalizeWeChatConnectModeSetting(raw string) string {
|
|||||||
switch strings.ToLower(strings.TrimSpace(raw)) {
|
switch strings.ToLower(strings.TrimSpace(raw)) {
|
||||||
case "mp":
|
case "mp":
|
||||||
return "mp"
|
return "mp"
|
||||||
|
case "mobile":
|
||||||
|
return "mobile"
|
||||||
default:
|
default:
|
||||||
return "open"
|
return "open"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultWeChatConnectScopeForMode(mode string) string {
|
func defaultWeChatConnectScopeForMode(mode string) string {
|
||||||
if normalizeWeChatConnectModeSetting(mode) == "mp" {
|
switch normalizeWeChatConnectModeSetting(mode) {
|
||||||
|
case "mp":
|
||||||
return "snsapi_userinfo"
|
return "snsapi_userinfo"
|
||||||
|
case "mobile":
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
return defaultWeChatConnectScopes
|
return defaultWeChatConnectScopes
|
||||||
}
|
}
|
||||||
@@ -204,37 +209,47 @@ func normalizeWeChatConnectScopeSetting(raw, mode string) string {
|
|||||||
default:
|
default:
|
||||||
return defaultWeChatConnectScopeForMode(mode)
|
return defaultWeChatConnectScopeForMode(mode)
|
||||||
}
|
}
|
||||||
|
case "mobile":
|
||||||
|
return ""
|
||||||
default:
|
default:
|
||||||
return defaultWeChatConnectScopes
|
return defaultWeChatConnectScopes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseWeChatConnectCapabilitySettings(settings map[string]string, enabled bool, mode string) (bool, bool) {
|
func parseWeChatConnectCapabilitySettings(settings map[string]string, enabled bool, mode string) (bool, bool, bool) {
|
||||||
mode = normalizeWeChatConnectModeSetting(mode)
|
mode = normalizeWeChatConnectModeSetting(mode)
|
||||||
rawOpen, hasOpen := settings[SettingKeyWeChatConnectOpenEnabled]
|
rawOpen, hasOpen := settings[SettingKeyWeChatConnectOpenEnabled]
|
||||||
rawMP, hasMP := settings[SettingKeyWeChatConnectMPEnabled]
|
rawMP, hasMP := settings[SettingKeyWeChatConnectMPEnabled]
|
||||||
|
rawMobile, hasMobile := settings[SettingKeyWeChatConnectMobileEnabled]
|
||||||
openConfigured := hasOpen && strings.TrimSpace(rawOpen) != ""
|
openConfigured := hasOpen && strings.TrimSpace(rawOpen) != ""
|
||||||
mpConfigured := hasMP && strings.TrimSpace(rawMP) != ""
|
mpConfigured := hasMP && strings.TrimSpace(rawMP) != ""
|
||||||
|
mobileConfigured := hasMobile && strings.TrimSpace(rawMobile) != ""
|
||||||
|
|
||||||
if openConfigured || mpConfigured {
|
if openConfigured || mpConfigured || mobileConfigured {
|
||||||
openEnabled := strings.TrimSpace(rawOpen) == "true"
|
openEnabled := strings.TrimSpace(rawOpen) == "true"
|
||||||
mpEnabled := strings.TrimSpace(rawMP) == "true"
|
mpEnabled := strings.TrimSpace(rawMP) == "true"
|
||||||
return openEnabled, mpEnabled
|
mobileEnabled := strings.TrimSpace(rawMobile) == "true"
|
||||||
|
return openEnabled, mpEnabled, mobileEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
if !enabled {
|
if !enabled {
|
||||||
return false, false
|
return false, false, false
|
||||||
}
|
}
|
||||||
if mode == "mp" {
|
if mode == "mp" {
|
||||||
return false, true
|
return false, true, false
|
||||||
}
|
}
|
||||||
return true, false
|
if mode == "mobile" {
|
||||||
|
return false, false, true
|
||||||
|
}
|
||||||
|
return true, false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeWeChatConnectStoredMode(openEnabled, mpEnabled bool, mode string) string {
|
func normalizeWeChatConnectStoredMode(openEnabled, mpEnabled, mobileEnabled bool, mode string) string {
|
||||||
switch {
|
switch {
|
||||||
case mpEnabled:
|
case mpEnabled:
|
||||||
return "mp"
|
return "mp"
|
||||||
|
case mobileEnabled:
|
||||||
|
return "mobile"
|
||||||
case openEnabled:
|
case openEnabled:
|
||||||
return "open"
|
return "open"
|
||||||
default:
|
default:
|
||||||
@@ -310,8 +325,15 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
|
|||||||
SettingKeyWeChatConnectEnabled,
|
SettingKeyWeChatConnectEnabled,
|
||||||
SettingKeyWeChatConnectAppID,
|
SettingKeyWeChatConnectAppID,
|
||||||
SettingKeyWeChatConnectAppSecret,
|
SettingKeyWeChatConnectAppSecret,
|
||||||
|
SettingKeyWeChatConnectOpenAppID,
|
||||||
|
SettingKeyWeChatConnectOpenAppSecret,
|
||||||
|
SettingKeyWeChatConnectMPAppID,
|
||||||
|
SettingKeyWeChatConnectMPAppSecret,
|
||||||
|
SettingKeyWeChatConnectMobileAppID,
|
||||||
|
SettingKeyWeChatConnectMobileAppSecret,
|
||||||
SettingKeyWeChatConnectOpenEnabled,
|
SettingKeyWeChatConnectOpenEnabled,
|
||||||
SettingKeyWeChatConnectMPEnabled,
|
SettingKeyWeChatConnectMPEnabled,
|
||||||
|
SettingKeyWeChatConnectMobileEnabled,
|
||||||
SettingKeyWeChatConnectMode,
|
SettingKeyWeChatConnectMode,
|
||||||
SettingKeyWeChatConnectScopes,
|
SettingKeyWeChatConnectScopes,
|
||||||
SettingKeyWeChatConnectRedirectURL,
|
SettingKeyWeChatConnectRedirectURL,
|
||||||
@@ -350,7 +372,7 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
|
|||||||
if oidcProviderName == "" {
|
if oidcProviderName == "" {
|
||||||
oidcProviderName = "OIDC"
|
oidcProviderName = "OIDC"
|
||||||
}
|
}
|
||||||
weChatEnabled, weChatOpenEnabled, weChatMPEnabled := s.weChatOAuthCapabilitiesFromSettings(settings)
|
weChatEnabled, weChatOpenEnabled, weChatMPEnabled, weChatMobileEnabled := s.weChatOAuthCapabilitiesFromSettings(settings)
|
||||||
|
|
||||||
// Password reset requires email verification to be enabled
|
// Password reset requires email verification to be enabled
|
||||||
emailVerifyEnabled := settings[SettingKeyEmailVerifyEnabled] == "true"
|
emailVerifyEnabled := settings[SettingKeyEmailVerifyEnabled] == "true"
|
||||||
@@ -397,6 +419,7 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
|
|||||||
WeChatOAuthEnabled: weChatEnabled,
|
WeChatOAuthEnabled: weChatEnabled,
|
||||||
WeChatOAuthOpenEnabled: weChatOpenEnabled,
|
WeChatOAuthOpenEnabled: weChatOpenEnabled,
|
||||||
WeChatOAuthMPEnabled: weChatMPEnabled,
|
WeChatOAuthMPEnabled: weChatMPEnabled,
|
||||||
|
WeChatOAuthMobileEnabled: weChatMobileEnabled,
|
||||||
BackendModeEnabled: settings[SettingKeyBackendModeEnabled] == "true",
|
BackendModeEnabled: settings[SettingKeyBackendModeEnabled] == "true",
|
||||||
PaymentEnabled: settings[SettingPaymentEnabled] == "true",
|
PaymentEnabled: settings[SettingPaymentEnabled] == "true",
|
||||||
OIDCOAuthEnabled: oidcEnabled,
|
OIDCOAuthEnabled: oidcEnabled,
|
||||||
@@ -456,6 +479,7 @@ func (s *SettingService) GetPublicSettingsForInjection(ctx context.Context) (any
|
|||||||
WeChatOAuthEnabled bool `json:"wechat_oauth_enabled"`
|
WeChatOAuthEnabled bool `json:"wechat_oauth_enabled"`
|
||||||
WeChatOAuthOpenEnabled bool `json:"wechat_oauth_open_enabled"`
|
WeChatOAuthOpenEnabled bool `json:"wechat_oauth_open_enabled"`
|
||||||
WeChatOAuthMPEnabled bool `json:"wechat_oauth_mp_enabled"`
|
WeChatOAuthMPEnabled bool `json:"wechat_oauth_mp_enabled"`
|
||||||
|
WeChatOAuthMobileEnabled bool `json:"wechat_oauth_mobile_enabled"`
|
||||||
BackendModeEnabled bool `json:"backend_mode_enabled"`
|
BackendModeEnabled bool `json:"backend_mode_enabled"`
|
||||||
PaymentEnabled bool `json:"payment_enabled"`
|
PaymentEnabled bool `json:"payment_enabled"`
|
||||||
OIDCOAuthEnabled bool `json:"oidc_oauth_enabled"`
|
OIDCOAuthEnabled bool `json:"oidc_oauth_enabled"`
|
||||||
@@ -493,6 +517,7 @@ func (s *SettingService) GetPublicSettingsForInjection(ctx context.Context) (any
|
|||||||
WeChatOAuthEnabled: settings.WeChatOAuthEnabled,
|
WeChatOAuthEnabled: settings.WeChatOAuthEnabled,
|
||||||
WeChatOAuthOpenEnabled: settings.WeChatOAuthOpenEnabled,
|
WeChatOAuthOpenEnabled: settings.WeChatOAuthOpenEnabled,
|
||||||
WeChatOAuthMPEnabled: settings.WeChatOAuthMPEnabled,
|
WeChatOAuthMPEnabled: settings.WeChatOAuthMPEnabled,
|
||||||
|
WeChatOAuthMobileEnabled: settings.WeChatOAuthMobileEnabled,
|
||||||
BackendModeEnabled: settings.BackendModeEnabled,
|
BackendModeEnabled: settings.BackendModeEnabled,
|
||||||
PaymentEnabled: settings.PaymentEnabled,
|
PaymentEnabled: settings.PaymentEnabled,
|
||||||
OIDCOAuthEnabled: settings.OIDCOAuthEnabled,
|
OIDCOAuthEnabled: settings.OIDCOAuthEnabled,
|
||||||
@@ -512,15 +537,22 @@ func DefaultWeChatConnectScopesForMode(mode string) string {
|
|||||||
func (s *SettingService) parseWeChatConnectOAuthConfig(settings map[string]string) (WeChatConnectOAuthConfig, error) {
|
func (s *SettingService) parseWeChatConnectOAuthConfig(settings map[string]string) (WeChatConnectOAuthConfig, error) {
|
||||||
enabled := settings[SettingKeyWeChatConnectEnabled] == "true"
|
enabled := settings[SettingKeyWeChatConnectEnabled] == "true"
|
||||||
mode := normalizeWeChatConnectModeSetting(settings[SettingKeyWeChatConnectMode])
|
mode := normalizeWeChatConnectModeSetting(settings[SettingKeyWeChatConnectMode])
|
||||||
openEnabled, mpEnabled := parseWeChatConnectCapabilitySettings(settings, enabled, mode)
|
openEnabled, mpEnabled, mobileEnabled := parseWeChatConnectCapabilitySettings(settings, enabled, mode)
|
||||||
mode = normalizeWeChatConnectStoredMode(openEnabled, mpEnabled, mode)
|
mode = normalizeWeChatConnectStoredMode(openEnabled, mpEnabled, mobileEnabled, mode)
|
||||||
|
|
||||||
cfg := WeChatConnectOAuthConfig{
|
cfg := WeChatConnectOAuthConfig{
|
||||||
Enabled: enabled,
|
Enabled: enabled,
|
||||||
AppID: strings.TrimSpace(settings[SettingKeyWeChatConnectAppID]),
|
LegacyAppID: strings.TrimSpace(settings[SettingKeyWeChatConnectAppID]),
|
||||||
AppSecret: strings.TrimSpace(settings[SettingKeyWeChatConnectAppSecret]),
|
LegacyAppSecret: strings.TrimSpace(settings[SettingKeyWeChatConnectAppSecret]),
|
||||||
|
OpenAppID: strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectOpenAppID], settings[SettingKeyWeChatConnectAppID])),
|
||||||
|
OpenAppSecret: strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectOpenAppSecret], settings[SettingKeyWeChatConnectAppSecret])),
|
||||||
|
MPAppID: strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMPAppID], settings[SettingKeyWeChatConnectAppID])),
|
||||||
|
MPAppSecret: strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMPAppSecret], settings[SettingKeyWeChatConnectAppSecret])),
|
||||||
|
MobileAppID: strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMobileAppID], settings[SettingKeyWeChatConnectAppID])),
|
||||||
|
MobileAppSecret: strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMobileAppSecret], settings[SettingKeyWeChatConnectAppSecret])),
|
||||||
OpenEnabled: openEnabled,
|
OpenEnabled: openEnabled,
|
||||||
MPEnabled: mpEnabled,
|
MPEnabled: mpEnabled,
|
||||||
|
MobileEnabled: mobileEnabled,
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
Scopes: normalizeWeChatConnectScopeSetting(settings[SettingKeyWeChatConnectScopes], mode),
|
Scopes: normalizeWeChatConnectScopeSetting(settings[SettingKeyWeChatConnectScopes], mode),
|
||||||
RedirectURL: strings.TrimSpace(settings[SettingKeyWeChatConnectRedirectURL]),
|
RedirectURL: strings.TrimSpace(settings[SettingKeyWeChatConnectRedirectURL]),
|
||||||
@@ -533,11 +565,29 @@ func (s *SettingService) parseWeChatConnectOAuthConfig(settings map[string]strin
|
|||||||
if !cfg.Enabled || (!cfg.OpenEnabled && !cfg.MPEnabled) {
|
if !cfg.Enabled || (!cfg.OpenEnabled && !cfg.MPEnabled) {
|
||||||
return WeChatConnectOAuthConfig{}, infraerrors.NotFound("OAUTH_DISABLED", "wechat oauth is disabled")
|
return WeChatConnectOAuthConfig{}, infraerrors.NotFound("OAUTH_DISABLED", "wechat oauth is disabled")
|
||||||
}
|
}
|
||||||
if cfg.AppID == "" {
|
if cfg.OpenEnabled {
|
||||||
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth app id not configured")
|
if cfg.AppIDForMode("open") == "" {
|
||||||
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth pc app id not configured")
|
||||||
|
}
|
||||||
|
if cfg.AppSecretForMode("open") == "" {
|
||||||
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth pc app secret not configured")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.MPEnabled {
|
||||||
|
if cfg.AppIDForMode("mp") == "" {
|
||||||
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth official account app id not configured")
|
||||||
|
}
|
||||||
|
if cfg.AppSecretForMode("mp") == "" {
|
||||||
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth official account app secret not configured")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.MobileEnabled {
|
||||||
|
if cfg.AppIDForMode("mobile") == "" {
|
||||||
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth mobile app id not configured")
|
||||||
|
}
|
||||||
|
if cfg.AppSecretForMode("mobile") == "" {
|
||||||
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth mobile app secret not configured")
|
||||||
}
|
}
|
||||||
if cfg.AppSecret == "" {
|
|
||||||
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth app secret not configured")
|
|
||||||
}
|
}
|
||||||
if cfg.RedirectURL == "" {
|
if cfg.RedirectURL == "" {
|
||||||
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth redirect url not configured")
|
return WeChatConnectOAuthConfig{}, infraerrors.InternalServer("OAUTH_CONFIG_INVALID", "wechat oauth redirect url not configured")
|
||||||
@@ -554,12 +604,34 @@ func (s *SettingService) parseWeChatConnectOAuthConfig(settings map[string]strin
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SettingService) weChatOAuthCapabilitiesFromSettings(settings map[string]string) (bool, bool, bool) {
|
func (s *SettingService) weChatOAuthCapabilitiesFromSettings(settings map[string]string) (bool, bool, bool, bool) {
|
||||||
cfg, err := s.parseWeChatConnectOAuthConfig(settings)
|
if settings[SettingKeyWeChatConnectEnabled] != "true" {
|
||||||
if err != nil {
|
return false, false, false, false
|
||||||
return false, false, false
|
|
||||||
}
|
}
|
||||||
return true, cfg.OpenEnabled, cfg.MPEnabled
|
|
||||||
|
mode := normalizeWeChatConnectModeSetting(settings[SettingKeyWeChatConnectMode])
|
||||||
|
openEnabled, mpEnabled, mobileEnabled := parseWeChatConnectCapabilitySettings(settings, true, mode)
|
||||||
|
redirectURL := strings.TrimSpace(settings[SettingKeyWeChatConnectRedirectURL])
|
||||||
|
frontendRedirectURL := strings.TrimSpace(settings[SettingKeyWeChatConnectFrontendRedirectURL])
|
||||||
|
if frontendRedirectURL == "" {
|
||||||
|
frontendRedirectURL = defaultWeChatConnectFrontend
|
||||||
|
}
|
||||||
|
|
||||||
|
legacyAppID := strings.TrimSpace(settings[SettingKeyWeChatConnectAppID])
|
||||||
|
legacyAppSecret := strings.TrimSpace(settings[SettingKeyWeChatConnectAppSecret])
|
||||||
|
openAppID := strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectOpenAppID], legacyAppID))
|
||||||
|
openAppSecret := strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectOpenAppSecret], legacyAppSecret))
|
||||||
|
mpAppID := strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMPAppID], legacyAppID))
|
||||||
|
mpAppSecret := strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMPAppSecret], legacyAppSecret))
|
||||||
|
mobileAppID := strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMobileAppID], legacyAppID))
|
||||||
|
mobileAppSecret := strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMobileAppSecret], legacyAppSecret))
|
||||||
|
|
||||||
|
webRedirectReady := redirectURL != "" && frontendRedirectURL != ""
|
||||||
|
openReady := openEnabled && webRedirectReady && openAppID != "" && openAppSecret != ""
|
||||||
|
mpReady := mpEnabled && webRedirectReady && mpAppID != "" && mpAppSecret != ""
|
||||||
|
mobileReady := mobileEnabled && mobileAppID != "" && mobileAppSecret != ""
|
||||||
|
|
||||||
|
return openReady || mpReady || mobileReady, openReady, mpReady, mobileReady
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterUserVisibleMenuItems filters out admin-only menu items from a raw JSON
|
// filterUserVisibleMenuItems filters out admin-only menu items from a raw JSON
|
||||||
@@ -744,9 +816,16 @@ func (s *SettingService) buildSystemSettingsUpdates(ctx context.Context, setting
|
|||||||
settings.PaymentVisibleMethodWxpaySource = wxpaySource
|
settings.PaymentVisibleMethodWxpaySource = wxpaySource
|
||||||
settings.WeChatConnectAppID = strings.TrimSpace(settings.WeChatConnectAppID)
|
settings.WeChatConnectAppID = strings.TrimSpace(settings.WeChatConnectAppID)
|
||||||
settings.WeChatConnectAppSecret = strings.TrimSpace(settings.WeChatConnectAppSecret)
|
settings.WeChatConnectAppSecret = strings.TrimSpace(settings.WeChatConnectAppSecret)
|
||||||
|
settings.WeChatConnectOpenAppID = strings.TrimSpace(firstNonEmpty(settings.WeChatConnectOpenAppID, settings.WeChatConnectAppID))
|
||||||
|
settings.WeChatConnectOpenAppSecret = strings.TrimSpace(firstNonEmpty(settings.WeChatConnectOpenAppSecret, settings.WeChatConnectAppSecret))
|
||||||
|
settings.WeChatConnectMPAppID = strings.TrimSpace(firstNonEmpty(settings.WeChatConnectMPAppID, settings.WeChatConnectAppID))
|
||||||
|
settings.WeChatConnectMPAppSecret = strings.TrimSpace(firstNonEmpty(settings.WeChatConnectMPAppSecret, settings.WeChatConnectAppSecret))
|
||||||
|
settings.WeChatConnectMobileAppID = strings.TrimSpace(firstNonEmpty(settings.WeChatConnectMobileAppID, settings.WeChatConnectAppID))
|
||||||
|
settings.WeChatConnectMobileAppSecret = strings.TrimSpace(firstNonEmpty(settings.WeChatConnectMobileAppSecret, settings.WeChatConnectAppSecret))
|
||||||
settings.WeChatConnectMode = normalizeWeChatConnectStoredMode(
|
settings.WeChatConnectMode = normalizeWeChatConnectStoredMode(
|
||||||
settings.WeChatConnectOpenEnabled,
|
settings.WeChatConnectOpenEnabled,
|
||||||
settings.WeChatConnectMPEnabled,
|
settings.WeChatConnectMPEnabled,
|
||||||
|
settings.WeChatConnectMobileEnabled,
|
||||||
settings.WeChatConnectMode,
|
settings.WeChatConnectMode,
|
||||||
)
|
)
|
||||||
settings.WeChatConnectScopes = normalizeWeChatConnectScopeSetting(settings.WeChatConnectScopes, settings.WeChatConnectMode)
|
settings.WeChatConnectScopes = normalizeWeChatConnectScopeSetting(settings.WeChatConnectScopes, settings.WeChatConnectMode)
|
||||||
@@ -827,8 +906,12 @@ func (s *SettingService) buildSystemSettingsUpdates(ctx context.Context, setting
|
|||||||
// WeChat Connect OAuth 登录
|
// WeChat Connect OAuth 登录
|
||||||
updates[SettingKeyWeChatConnectEnabled] = strconv.FormatBool(settings.WeChatConnectEnabled)
|
updates[SettingKeyWeChatConnectEnabled] = strconv.FormatBool(settings.WeChatConnectEnabled)
|
||||||
updates[SettingKeyWeChatConnectAppID] = settings.WeChatConnectAppID
|
updates[SettingKeyWeChatConnectAppID] = settings.WeChatConnectAppID
|
||||||
|
updates[SettingKeyWeChatConnectOpenAppID] = settings.WeChatConnectOpenAppID
|
||||||
|
updates[SettingKeyWeChatConnectMPAppID] = settings.WeChatConnectMPAppID
|
||||||
|
updates[SettingKeyWeChatConnectMobileAppID] = settings.WeChatConnectMobileAppID
|
||||||
updates[SettingKeyWeChatConnectOpenEnabled] = strconv.FormatBool(settings.WeChatConnectOpenEnabled)
|
updates[SettingKeyWeChatConnectOpenEnabled] = strconv.FormatBool(settings.WeChatConnectOpenEnabled)
|
||||||
updates[SettingKeyWeChatConnectMPEnabled] = strconv.FormatBool(settings.WeChatConnectMPEnabled)
|
updates[SettingKeyWeChatConnectMPEnabled] = strconv.FormatBool(settings.WeChatConnectMPEnabled)
|
||||||
|
updates[SettingKeyWeChatConnectMobileEnabled] = strconv.FormatBool(settings.WeChatConnectMobileEnabled)
|
||||||
updates[SettingKeyWeChatConnectMode] = settings.WeChatConnectMode
|
updates[SettingKeyWeChatConnectMode] = settings.WeChatConnectMode
|
||||||
updates[SettingKeyWeChatConnectScopes] = settings.WeChatConnectScopes
|
updates[SettingKeyWeChatConnectScopes] = settings.WeChatConnectScopes
|
||||||
updates[SettingKeyWeChatConnectRedirectURL] = settings.WeChatConnectRedirectURL
|
updates[SettingKeyWeChatConnectRedirectURL] = settings.WeChatConnectRedirectURL
|
||||||
@@ -836,6 +919,15 @@ func (s *SettingService) buildSystemSettingsUpdates(ctx context.Context, setting
|
|||||||
if settings.WeChatConnectAppSecret != "" {
|
if settings.WeChatConnectAppSecret != "" {
|
||||||
updates[SettingKeyWeChatConnectAppSecret] = settings.WeChatConnectAppSecret
|
updates[SettingKeyWeChatConnectAppSecret] = settings.WeChatConnectAppSecret
|
||||||
}
|
}
|
||||||
|
if settings.WeChatConnectOpenAppSecret != "" {
|
||||||
|
updates[SettingKeyWeChatConnectOpenAppSecret] = settings.WeChatConnectOpenAppSecret
|
||||||
|
}
|
||||||
|
if settings.WeChatConnectMPAppSecret != "" {
|
||||||
|
updates[SettingKeyWeChatConnectMPAppSecret] = settings.WeChatConnectMPAppSecret
|
||||||
|
}
|
||||||
|
if settings.WeChatConnectMobileAppSecret != "" {
|
||||||
|
updates[SettingKeyWeChatConnectMobileAppSecret] = settings.WeChatConnectMobileAppSecret
|
||||||
|
}
|
||||||
|
|
||||||
// OEM设置
|
// OEM设置
|
||||||
updates[SettingKeySiteName] = settings.SiteName
|
updates[SettingKeySiteName] = settings.SiteName
|
||||||
@@ -1344,8 +1436,15 @@ func (s *SettingService) InitializeDefaultSettings(ctx context.Context) error {
|
|||||||
SettingKeyCustomMenuItems: "[]",
|
SettingKeyCustomMenuItems: "[]",
|
||||||
SettingKeyCustomEndpoints: "[]",
|
SettingKeyCustomEndpoints: "[]",
|
||||||
SettingKeyWeChatConnectEnabled: "false",
|
SettingKeyWeChatConnectEnabled: "false",
|
||||||
|
SettingKeyWeChatConnectOpenAppID: "",
|
||||||
|
SettingKeyWeChatConnectOpenAppSecret: "",
|
||||||
|
SettingKeyWeChatConnectMPAppID: "",
|
||||||
|
SettingKeyWeChatConnectMPAppSecret: "",
|
||||||
|
SettingKeyWeChatConnectMobileAppID: "",
|
||||||
|
SettingKeyWeChatConnectMobileAppSecret: "",
|
||||||
SettingKeyWeChatConnectOpenEnabled: "false",
|
SettingKeyWeChatConnectOpenEnabled: "false",
|
||||||
SettingKeyWeChatConnectMPEnabled: "false",
|
SettingKeyWeChatConnectMPEnabled: "false",
|
||||||
|
SettingKeyWeChatConnectMobileEnabled: "false",
|
||||||
SettingKeyWeChatConnectMode: "open",
|
SettingKeyWeChatConnectMode: "open",
|
||||||
SettingKeyWeChatConnectScopes: "snsapi_login",
|
SettingKeyWeChatConnectScopes: "snsapi_login",
|
||||||
SettingKeyWeChatConnectFrontendRedirectURL: defaultWeChatConnectFrontend,
|
SettingKeyWeChatConnectFrontendRedirectURL: defaultWeChatConnectFrontend,
|
||||||
@@ -1645,7 +1744,16 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
|
|||||||
result.WeChatConnectAppID = strings.TrimSpace(settings[SettingKeyWeChatConnectAppID])
|
result.WeChatConnectAppID = strings.TrimSpace(settings[SettingKeyWeChatConnectAppID])
|
||||||
result.WeChatConnectAppSecret = strings.TrimSpace(settings[SettingKeyWeChatConnectAppSecret])
|
result.WeChatConnectAppSecret = strings.TrimSpace(settings[SettingKeyWeChatConnectAppSecret])
|
||||||
result.WeChatConnectAppSecretConfigured = result.WeChatConnectAppSecret != ""
|
result.WeChatConnectAppSecretConfigured = result.WeChatConnectAppSecret != ""
|
||||||
result.WeChatConnectOpenEnabled, result.WeChatConnectMPEnabled = parseWeChatConnectCapabilitySettings(
|
result.WeChatConnectOpenAppID = strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectOpenAppID], result.WeChatConnectAppID))
|
||||||
|
result.WeChatConnectOpenAppSecret = strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectOpenAppSecret], result.WeChatConnectAppSecret))
|
||||||
|
result.WeChatConnectOpenAppSecretConfigured = result.WeChatConnectOpenAppSecret != ""
|
||||||
|
result.WeChatConnectMPAppID = strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMPAppID], result.WeChatConnectAppID))
|
||||||
|
result.WeChatConnectMPAppSecret = strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMPAppSecret], result.WeChatConnectAppSecret))
|
||||||
|
result.WeChatConnectMPAppSecretConfigured = result.WeChatConnectMPAppSecret != ""
|
||||||
|
result.WeChatConnectMobileAppID = strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMobileAppID], result.WeChatConnectAppID))
|
||||||
|
result.WeChatConnectMobileAppSecret = strings.TrimSpace(firstNonEmpty(settings[SettingKeyWeChatConnectMobileAppSecret], result.WeChatConnectAppSecret))
|
||||||
|
result.WeChatConnectMobileAppSecretConfigured = result.WeChatConnectMobileAppSecret != ""
|
||||||
|
result.WeChatConnectOpenEnabled, result.WeChatConnectMPEnabled, result.WeChatConnectMobileEnabled = parseWeChatConnectCapabilitySettings(
|
||||||
settings,
|
settings,
|
||||||
result.WeChatConnectEnabled,
|
result.WeChatConnectEnabled,
|
||||||
settings[SettingKeyWeChatConnectMode],
|
settings[SettingKeyWeChatConnectMode],
|
||||||
@@ -1653,6 +1761,7 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
|
|||||||
result.WeChatConnectMode = normalizeWeChatConnectStoredMode(
|
result.WeChatConnectMode = normalizeWeChatConnectStoredMode(
|
||||||
result.WeChatConnectOpenEnabled,
|
result.WeChatConnectOpenEnabled,
|
||||||
result.WeChatConnectMPEnabled,
|
result.WeChatConnectMPEnabled,
|
||||||
|
result.WeChatConnectMobileEnabled,
|
||||||
settings[SettingKeyWeChatConnectMode],
|
settings[SettingKeyWeChatConnectMode],
|
||||||
)
|
)
|
||||||
result.WeChatConnectScopes = normalizeWeChatConnectScopeSetting(settings[SettingKeyWeChatConnectScopes], result.WeChatConnectMode)
|
result.WeChatConnectScopes = normalizeWeChatConnectScopeSetting(settings[SettingKeyWeChatConnectScopes], result.WeChatConnectMode)
|
||||||
@@ -2151,8 +2260,15 @@ func (s *SettingService) GetWeChatConnectOAuthConfig(ctx context.Context) (WeCha
|
|||||||
SettingKeyWeChatConnectEnabled,
|
SettingKeyWeChatConnectEnabled,
|
||||||
SettingKeyWeChatConnectAppID,
|
SettingKeyWeChatConnectAppID,
|
||||||
SettingKeyWeChatConnectAppSecret,
|
SettingKeyWeChatConnectAppSecret,
|
||||||
|
SettingKeyWeChatConnectOpenAppID,
|
||||||
|
SettingKeyWeChatConnectOpenAppSecret,
|
||||||
|
SettingKeyWeChatConnectMPAppID,
|
||||||
|
SettingKeyWeChatConnectMPAppSecret,
|
||||||
|
SettingKeyWeChatConnectMobileAppID,
|
||||||
|
SettingKeyWeChatConnectMobileAppSecret,
|
||||||
SettingKeyWeChatConnectOpenEnabled,
|
SettingKeyWeChatConnectOpenEnabled,
|
||||||
SettingKeyWeChatConnectMPEnabled,
|
SettingKeyWeChatConnectMPEnabled,
|
||||||
|
SettingKeyWeChatConnectMobileEnabled,
|
||||||
SettingKeyWeChatConnectMode,
|
SettingKeyWeChatConnectMode,
|
||||||
SettingKeyWeChatConnectScopes,
|
SettingKeyWeChatConnectScopes,
|
||||||
SettingKeyWeChatConnectRedirectURL,
|
SettingKeyWeChatConnectRedirectURL,
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
func firstNonEmpty(values ...string) string {
|
||||||
|
for _, value := range values {
|
||||||
|
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
||||||
|
return trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type SystemSettings struct {
|
type SystemSettings struct {
|
||||||
RegistrationEnabled bool
|
RegistrationEnabled bool
|
||||||
EmailVerifyEnabled bool
|
EmailVerifyEnabled bool
|
||||||
@@ -36,8 +47,18 @@ type SystemSettings struct {
|
|||||||
WeChatConnectAppID string
|
WeChatConnectAppID string
|
||||||
WeChatConnectAppSecret string
|
WeChatConnectAppSecret string
|
||||||
WeChatConnectAppSecretConfigured bool
|
WeChatConnectAppSecretConfigured bool
|
||||||
|
WeChatConnectOpenAppID string
|
||||||
|
WeChatConnectOpenAppSecret string
|
||||||
|
WeChatConnectOpenAppSecretConfigured bool
|
||||||
|
WeChatConnectMPAppID string
|
||||||
|
WeChatConnectMPAppSecret string
|
||||||
|
WeChatConnectMPAppSecretConfigured bool
|
||||||
|
WeChatConnectMobileAppID string
|
||||||
|
WeChatConnectMobileAppSecret string
|
||||||
|
WeChatConnectMobileAppSecretConfigured bool
|
||||||
WeChatConnectOpenEnabled bool
|
WeChatConnectOpenEnabled bool
|
||||||
WeChatConnectMPEnabled bool
|
WeChatConnectMPEnabled bool
|
||||||
|
WeChatConnectMobileEnabled bool
|
||||||
WeChatConnectMode string
|
WeChatConnectMode string
|
||||||
WeChatConnectScopes string
|
WeChatConnectScopes string
|
||||||
WeChatConnectRedirectURL string
|
WeChatConnectRedirectURL string
|
||||||
@@ -177,6 +198,7 @@ type PublicSettings struct {
|
|||||||
WeChatOAuthEnabled bool
|
WeChatOAuthEnabled bool
|
||||||
WeChatOAuthOpenEnabled bool
|
WeChatOAuthOpenEnabled bool
|
||||||
WeChatOAuthMPEnabled bool
|
WeChatOAuthMPEnabled bool
|
||||||
|
WeChatOAuthMobileEnabled bool
|
||||||
BackendModeEnabled bool
|
BackendModeEnabled bool
|
||||||
PaymentEnabled bool
|
PaymentEnabled bool
|
||||||
OIDCOAuthEnabled bool
|
OIDCOAuthEnabled bool
|
||||||
@@ -191,10 +213,17 @@ type PublicSettings struct {
|
|||||||
|
|
||||||
type WeChatConnectOAuthConfig struct {
|
type WeChatConnectOAuthConfig struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
AppID string
|
LegacyAppID string
|
||||||
AppSecret string
|
LegacyAppSecret string
|
||||||
|
OpenAppID string
|
||||||
|
OpenAppSecret string
|
||||||
|
MPAppID string
|
||||||
|
MPAppSecret string
|
||||||
|
MobileAppID string
|
||||||
|
MobileAppSecret string
|
||||||
OpenEnabled bool
|
OpenEnabled bool
|
||||||
MPEnabled bool
|
MPEnabled bool
|
||||||
|
MobileEnabled bool
|
||||||
Mode string
|
Mode string
|
||||||
Scopes string
|
Scopes string
|
||||||
RedirectURL string
|
RedirectURL string
|
||||||
@@ -205,18 +234,43 @@ func (cfg WeChatConnectOAuthConfig) SupportsMode(mode string) bool {
|
|||||||
switch normalizeWeChatConnectModeSetting(mode) {
|
switch normalizeWeChatConnectModeSetting(mode) {
|
||||||
case "mp":
|
case "mp":
|
||||||
return cfg.MPEnabled
|
return cfg.MPEnabled
|
||||||
|
case "mobile":
|
||||||
|
return cfg.MobileEnabled
|
||||||
default:
|
default:
|
||||||
return cfg.OpenEnabled
|
return cfg.OpenEnabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg WeChatConnectOAuthConfig) ScopeForMode(mode string) string {
|
func (cfg WeChatConnectOAuthConfig) ScopeForMode(mode string) string {
|
||||||
if normalizeWeChatConnectModeSetting(mode) == "mp" {
|
switch normalizeWeChatConnectModeSetting(mode) {
|
||||||
|
case "mp":
|
||||||
return normalizeWeChatConnectScopeSetting(cfg.Scopes, "mp")
|
return normalizeWeChatConnectScopeSetting(cfg.Scopes, "mp")
|
||||||
|
case "mobile":
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
return defaultWeChatConnectScopeForMode("open")
|
return defaultWeChatConnectScopeForMode("open")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg WeChatConnectOAuthConfig) AppIDForMode(mode string) string {
|
||||||
|
switch normalizeWeChatConnectModeSetting(mode) {
|
||||||
|
case "mp":
|
||||||
|
return strings.TrimSpace(firstNonEmpty(cfg.MPAppID, cfg.LegacyAppID))
|
||||||
|
case "mobile":
|
||||||
|
return strings.TrimSpace(firstNonEmpty(cfg.MobileAppID, cfg.LegacyAppID))
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(firstNonEmpty(cfg.OpenAppID, cfg.LegacyAppID))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg WeChatConnectOAuthConfig) AppSecretForMode(mode string) string {
|
||||||
|
switch normalizeWeChatConnectModeSetting(mode) {
|
||||||
|
case "mp":
|
||||||
|
return strings.TrimSpace(firstNonEmpty(cfg.MPAppSecret, cfg.LegacyAppSecret))
|
||||||
|
case "mobile":
|
||||||
|
return strings.TrimSpace(firstNonEmpty(cfg.MobileAppSecret, cfg.LegacyAppSecret))
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(firstNonEmpty(cfg.OpenAppSecret, cfg.LegacyAppSecret))
|
||||||
|
}
|
||||||
|
|
||||||
// StreamTimeoutSettings 流超时处理配置(仅控制超时后的处理方式,超时判定由网关配置控制)
|
// StreamTimeoutSettings 流超时处理配置(仅控制超时后的处理方式,超时判定由网关配置控制)
|
||||||
type StreamTimeoutSettings struct {
|
type StreamTimeoutSettings struct {
|
||||||
// Enabled 是否启用流超时处理
|
// Enabled 是否启用流超时处理
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export type PaymentVisibleMethodSource =
|
|||||||
| "easypay_alipay"
|
| "easypay_alipay"
|
||||||
| "official_wxpay"
|
| "official_wxpay"
|
||||||
| "easypay_wxpay";
|
| "easypay_wxpay";
|
||||||
export type WeChatConnectMode = "open" | "mp";
|
export type WeChatConnectMode = "open" | "mp" | "mobile";
|
||||||
|
|
||||||
export interface PaymentVisibleMethodSourceOption {
|
export interface PaymentVisibleMethodSourceOption {
|
||||||
value: PaymentVisibleMethodSource;
|
value: PaymentVisibleMethodSource;
|
||||||
@@ -108,11 +108,16 @@ const PAYMENT_VISIBLE_METHOD_SOURCE_ALIASES: Record<
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const WECHAT_CONNECT_MODE_OPTIONS: WeChatConnectModeOption[] = [
|
const WECHAT_CONNECT_MODE_OPTIONS: WeChatConnectModeOption[] = [
|
||||||
{ value: "open", labelZh: "微信开放平台", labelEn: "WeChat Open Platform" },
|
{ value: "open", labelZh: "PC 应用", labelEn: "PC App" },
|
||||||
{
|
{
|
||||||
value: "mp",
|
value: "mp",
|
||||||
labelZh: "微信公众号 / 小程序",
|
labelZh: "公众号",
|
||||||
labelEn: "WeChat Official Account / Mini Program",
|
labelEn: "Official Account",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "mobile",
|
||||||
|
labelZh: "移动应用",
|
||||||
|
labelEn: "Mobile App",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const WECHAT_CONNECT_MODE_ALIASES: Record<string, WeChatConnectMode> = {
|
const WECHAT_CONNECT_MODE_ALIASES: Record<string, WeChatConnectMode> = {
|
||||||
@@ -124,6 +129,9 @@ const WECHAT_CONNECT_MODE_ALIASES: Record<string, WeChatConnectMode> = {
|
|||||||
official_account: "mp",
|
official_account: "mp",
|
||||||
wechat_mp: "mp",
|
wechat_mp: "mp",
|
||||||
mini_program: "mp",
|
mini_program: "mp",
|
||||||
|
mobile: "mobile",
|
||||||
|
mobile_app: "mobile",
|
||||||
|
native_app: "mobile",
|
||||||
};
|
};
|
||||||
|
|
||||||
export function normalizeDefaultSubscriptionSettings(
|
export function normalizeDefaultSubscriptionSettings(
|
||||||
@@ -234,34 +242,52 @@ export function normalizeWeChatConnectMode(source: unknown): WeChatConnectMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function defaultWeChatConnectScopesForMode(mode: unknown): string {
|
export function defaultWeChatConnectScopesForMode(mode: unknown): string {
|
||||||
return normalizeWeChatConnectMode(mode) === "mp"
|
switch (normalizeWeChatConnectMode(mode)) {
|
||||||
? "snsapi_userinfo"
|
case "mp":
|
||||||
: "snsapi_login";
|
return "snsapi_userinfo";
|
||||||
|
case "mobile":
|
||||||
|
return "";
|
||||||
|
default:
|
||||||
|
return "snsapi_login";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveWeChatConnectModeCapabilities(
|
export function resolveWeChatConnectModeCapabilities(
|
||||||
openEnabled: unknown,
|
openEnabled: unknown,
|
||||||
mpEnabled: unknown,
|
mpEnabled: unknown,
|
||||||
|
mobileEnabled: unknown,
|
||||||
legacyMode: unknown,
|
legacyMode: unknown,
|
||||||
): { openEnabled: boolean; mpEnabled: boolean } {
|
): { openEnabled: boolean; mpEnabled: boolean; mobileEnabled: boolean } {
|
||||||
if (typeof openEnabled === "boolean" || typeof mpEnabled === "boolean") {
|
if (
|
||||||
|
typeof openEnabled === "boolean" ||
|
||||||
|
typeof mpEnabled === "boolean" ||
|
||||||
|
typeof mobileEnabled === "boolean"
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
openEnabled: openEnabled === true,
|
openEnabled: openEnabled === true,
|
||||||
mpEnabled: mpEnabled === true,
|
mpEnabled: mpEnabled === true,
|
||||||
|
mobileEnabled: mobileEnabled === true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalizeWeChatConnectMode(legacyMode) === "mp"
|
switch (normalizeWeChatConnectMode(legacyMode)) {
|
||||||
? { openEnabled: false, mpEnabled: true }
|
case "mp":
|
||||||
: { openEnabled: true, mpEnabled: false };
|
return { openEnabled: false, mpEnabled: true, mobileEnabled: false };
|
||||||
|
case "mobile":
|
||||||
|
return { openEnabled: false, mpEnabled: false, mobileEnabled: true };
|
||||||
|
default:
|
||||||
|
return { openEnabled: true, mpEnabled: false, mobileEnabled: false };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deriveWeChatConnectStoredMode(
|
export function deriveWeChatConnectStoredMode(
|
||||||
openEnabled: boolean,
|
openEnabled: boolean,
|
||||||
mpEnabled: boolean,
|
mpEnabled: boolean,
|
||||||
|
mobileEnabled: boolean,
|
||||||
legacyMode: unknown,
|
legacyMode: unknown,
|
||||||
): WeChatConnectMode {
|
): WeChatConnectMode {
|
||||||
if (mpEnabled) return "mp";
|
if (mpEnabled) return "mp";
|
||||||
|
if (mobileEnabled) return "mobile";
|
||||||
if (openEnabled) return "open";
|
if (openEnabled) return "open";
|
||||||
return normalizeWeChatConnectMode(legacyMode);
|
return normalizeWeChatConnectMode(legacyMode);
|
||||||
}
|
}
|
||||||
@@ -342,8 +368,15 @@ export interface SystemSettings {
|
|||||||
wechat_connect_enabled: boolean;
|
wechat_connect_enabled: boolean;
|
||||||
wechat_connect_app_id: string;
|
wechat_connect_app_id: string;
|
||||||
wechat_connect_app_secret_configured: boolean;
|
wechat_connect_app_secret_configured: boolean;
|
||||||
|
wechat_connect_open_app_id?: string;
|
||||||
|
wechat_connect_open_app_secret_configured?: boolean;
|
||||||
|
wechat_connect_mp_app_id?: string;
|
||||||
|
wechat_connect_mp_app_secret_configured?: boolean;
|
||||||
|
wechat_connect_mobile_app_id?: string;
|
||||||
|
wechat_connect_mobile_app_secret_configured?: boolean;
|
||||||
wechat_connect_open_enabled?: boolean;
|
wechat_connect_open_enabled?: boolean;
|
||||||
wechat_connect_mp_enabled?: boolean;
|
wechat_connect_mp_enabled?: boolean;
|
||||||
|
wechat_connect_mobile_enabled?: boolean;
|
||||||
wechat_connect_mode: string;
|
wechat_connect_mode: string;
|
||||||
wechat_connect_scopes: string;
|
wechat_connect_scopes: string;
|
||||||
wechat_connect_redirect_url: string;
|
wechat_connect_redirect_url: string;
|
||||||
@@ -501,8 +534,15 @@ export interface UpdateSettingsRequest {
|
|||||||
wechat_connect_enabled?: boolean;
|
wechat_connect_enabled?: boolean;
|
||||||
wechat_connect_app_id?: string;
|
wechat_connect_app_id?: string;
|
||||||
wechat_connect_app_secret?: string;
|
wechat_connect_app_secret?: string;
|
||||||
|
wechat_connect_open_app_id?: string;
|
||||||
|
wechat_connect_open_app_secret?: string;
|
||||||
|
wechat_connect_mp_app_id?: string;
|
||||||
|
wechat_connect_mp_app_secret?: string;
|
||||||
|
wechat_connect_mobile_app_id?: string;
|
||||||
|
wechat_connect_mobile_app_secret?: string;
|
||||||
wechat_connect_open_enabled?: boolean;
|
wechat_connect_open_enabled?: boolean;
|
||||||
wechat_connect_mp_enabled?: boolean;
|
wechat_connect_mp_enabled?: boolean;
|
||||||
|
wechat_connect_mobile_enabled?: boolean;
|
||||||
wechat_connect_mode?: string;
|
wechat_connect_mode?: string;
|
||||||
wechat_connect_scopes?: string;
|
wechat_connect_scopes?: string;
|
||||||
wechat_connect_redirect_url?: string;
|
wechat_connect_redirect_url?: string;
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ const disabledHint = computed(() => {
|
|||||||
return t('auth.oauthFlow.wechatSystemBrowserOnly')
|
return t('auth.oauthFlow.wechatSystemBrowserOnly')
|
||||||
case 'wechat_browser_required':
|
case 'wechat_browser_required':
|
||||||
return t('auth.oauthFlow.wechatBrowserOnly')
|
return t('auth.oauthFlow.wechatBrowserOnly')
|
||||||
|
case 'native_app_required':
|
||||||
|
return localizeWeChatHint(
|
||||||
|
'当前仅配置微信移动应用登录,需要在原生 App 中通过微信 SDK 发起授权。',
|
||||||
|
'This site only has WeChat mobile app login configured. Continue from the native app through the WeChat SDK.',
|
||||||
|
)
|
||||||
case 'not_configured':
|
case 'not_configured':
|
||||||
return t('auth.oauthFlow.wechatNotConfigured')
|
return t('auth.oauthFlow.wechatNotConfigured')
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ export const useAppStore = defineStore('app', () => {
|
|||||||
wechat_oauth_enabled: false,
|
wechat_oauth_enabled: false,
|
||||||
wechat_oauth_open_enabled: false,
|
wechat_oauth_open_enabled: false,
|
||||||
wechat_oauth_mp_enabled: false,
|
wechat_oauth_mp_enabled: false,
|
||||||
|
wechat_oauth_mobile_enabled: false,
|
||||||
oidc_oauth_enabled: false,
|
oidc_oauth_enabled: false,
|
||||||
oidc_oauth_provider_name: 'OIDC',
|
oidc_oauth_provider_name: 'OIDC',
|
||||||
backend_mode_enabled: false,
|
backend_mode_enabled: false,
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ export interface PublicSettings {
|
|||||||
wechat_oauth_enabled: boolean
|
wechat_oauth_enabled: boolean
|
||||||
wechat_oauth_open_enabled?: boolean
|
wechat_oauth_open_enabled?: boolean
|
||||||
wechat_oauth_mp_enabled?: boolean
|
wechat_oauth_mp_enabled?: boolean
|
||||||
|
wechat_oauth_mobile_enabled?: boolean
|
||||||
oidc_oauth_enabled: boolean
|
oidc_oauth_enabled: boolean
|
||||||
oidc_oauth_provider_name: string
|
oidc_oauth_provider_name: string
|
||||||
backend_mode_enabled: boolean
|
backend_mode_enabled: boolean
|
||||||
|
|||||||
@@ -1398,101 +1398,253 @@
|
|||||||
v-if="form.wechat_connect_enabled"
|
v-if="form.wechat_connect_enabled"
|
||||||
class="space-y-6 border-t border-gray-100 pt-4 dark:border-dark-700"
|
class="space-y-6 border-t border-gray-100 pt-4 dark:border-dark-700"
|
||||||
>
|
>
|
||||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
<div class="space-y-4">
|
||||||
<div>
|
<div
|
||||||
<label
|
class="rounded-lg border border-gray-200 p-4 dark:border-dark-700"
|
||||||
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
||||||
>
|
>
|
||||||
{{ t("admin.settings.wechatConnect.appIdLabel") }}
|
<div class="flex items-start justify-between gap-4">
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
data-testid="wechat-connect-app-id"
|
|
||||||
v-model="form.wechat_connect_app_id"
|
|
||||||
type="text"
|
|
||||||
class="input font-mono text-sm"
|
|
||||||
:placeholder="t('admin.settings.wechatConnect.appIdPlaceholder')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label
|
<h3 class="font-medium text-gray-900 dark:text-white">
|
||||||
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
{{ localText("PC 应用", "PC App") }}
|
||||||
>
|
</h3>
|
||||||
{{ t("admin.settings.wechatConnect.appSecretLabel") }}
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
data-testid="wechat-connect-app-secret"
|
|
||||||
v-model="form.wechat_connect_app_secret"
|
|
||||||
type="password"
|
|
||||||
class="input font-mono text-sm"
|
|
||||||
:placeholder="
|
|
||||||
form.wechat_connect_app_secret_configured
|
|
||||||
? t('admin.settings.wechatConnect.appSecretConfiguredPlaceholder')
|
|
||||||
: t('admin.settings.wechatConnect.appSecretPlaceholder')
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<p class="mt-1.5 text-xs text-gray-500 dark:text-gray-400">
|
|
||||||
{{
|
{{
|
||||||
form.wechat_connect_app_secret_configured
|
localText(
|
||||||
? t('admin.settings.wechatConnect.appSecretConfiguredHint')
|
"桌面浏览器通过微信开放平台扫码登录。可与公众号或移动应用同时存在。",
|
||||||
: t('admin.settings.wechatConnect.appSecretHint')
|
"Desktop browsers sign in through WeChat Open Platform QR login. This can coexist with Official Account or Mobile App.",
|
||||||
|
)
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<Toggle
|
||||||
|
:model-value="form.wechat_connect_open_enabled"
|
||||||
|
data-testid="wechat-connect-open-enabled"
|
||||||
|
@update:model-value="handleWeChatOpenEnabledChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="form.wechat_connect_open_enabled"
|
||||||
|
class="mt-4 grid grid-cols-1 gap-4 lg:grid-cols-2"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{{ localText("PC AppID", "PC App ID") }}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="form.wechat_connect_open_app_id"
|
||||||
|
type="text"
|
||||||
|
class="input font-mono text-sm"
|
||||||
|
:placeholder="
|
||||||
|
localText(
|
||||||
|
'微信开放平台 PC 应用 AppID',
|
||||||
|
'WeChat Open Platform PC App ID',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{{ localText("PC AppSecret", "PC App Secret") }}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="form.wechat_connect_open_app_secret"
|
||||||
|
type="password"
|
||||||
|
class="input font-mono text-sm"
|
||||||
|
:placeholder="
|
||||||
|
form.wechat_connect_open_app_secret_configured
|
||||||
|
? localText(
|
||||||
|
'密钥已配置,留空以保留当前值。',
|
||||||
|
'Secret configured. Leave empty to keep the current value.',
|
||||||
|
)
|
||||||
|
: localText(
|
||||||
|
'微信开放平台 PC 应用 AppSecret',
|
||||||
|
'WeChat Open Platform PC App Secret',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="rounded-lg border border-gray-200 p-4 dark:border-dark-700"
|
||||||
|
>
|
||||||
|
<div class="flex items-start justify-between gap-4">
|
||||||
|
<div>
|
||||||
|
<h3 class="font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ localText("公众号", "Official Account") }}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
{{
|
||||||
|
localText(
|
||||||
|
"仅在微信内浏览器可用;非微信环境下会显示不可用。",
|
||||||
|
"Only available inside the WeChat browser. It is shown as unavailable outside WeChat.",
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Toggle
|
||||||
|
:model-value="form.wechat_connect_mp_enabled"
|
||||||
|
data-testid="wechat-connect-mp-enabled"
|
||||||
|
@update:model-value="handleWeChatMPEnabledChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="form.wechat_connect_mp_enabled"
|
||||||
|
class="mt-4 grid grid-cols-1 gap-4 lg:grid-cols-2"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{{ localText("公众号 AppID", "Official Account App ID") }}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="form.wechat_connect_mp_app_id"
|
||||||
|
type="text"
|
||||||
|
class="input font-mono text-sm"
|
||||||
|
:placeholder="
|
||||||
|
localText(
|
||||||
|
'公众号 AppID',
|
||||||
|
'Official Account App ID',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
localText(
|
||||||
|
"公众号 AppSecret",
|
||||||
|
"Official Account App Secret",
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="form.wechat_connect_mp_app_secret"
|
||||||
|
type="password"
|
||||||
|
class="input font-mono text-sm"
|
||||||
|
:placeholder="
|
||||||
|
form.wechat_connect_mp_app_secret_configured
|
||||||
|
? localText(
|
||||||
|
'密钥已配置,留空以保留当前值。',
|
||||||
|
'Secret configured. Leave empty to keep the current value.',
|
||||||
|
)
|
||||||
|
: localText(
|
||||||
|
'公众号 AppSecret',
|
||||||
|
'Official Account App Secret',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="rounded-lg border border-gray-200 p-4 dark:border-dark-700"
|
||||||
|
>
|
||||||
|
<div class="flex items-start justify-between gap-4">
|
||||||
|
<div>
|
||||||
|
<h3 class="font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ localText("移动应用", "Mobile App") }}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
{{
|
||||||
|
localText(
|
||||||
|
"原生移动端通过微信 SDK 唤起授权,网页端不会直接发起该流程。",
|
||||||
|
"Native mobile clients start authorization through the WeChat SDK. The web UI does not launch this flow directly.",
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Toggle
|
||||||
|
:model-value="form.wechat_connect_mobile_enabled"
|
||||||
|
data-testid="wechat-connect-mobile-enabled"
|
||||||
|
@update:model-value="handleWeChatMobileEnabledChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="form.wechat_connect_mobile_enabled"
|
||||||
|
class="mt-4 grid grid-cols-1 gap-4 lg:grid-cols-2"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{{ localText("移动应用 AppID", "Mobile App ID") }}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="form.wechat_connect_mobile_app_id"
|
||||||
|
type="text"
|
||||||
|
class="input font-mono text-sm"
|
||||||
|
:placeholder="
|
||||||
|
localText(
|
||||||
|
'移动应用 AppID',
|
||||||
|
'Mobile App ID',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{{ localText("移动应用 AppSecret", "Mobile App Secret") }}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="form.wechat_connect_mobile_app_secret"
|
||||||
|
type="password"
|
||||||
|
class="input font-mono text-sm"
|
||||||
|
:placeholder="
|
||||||
|
form.wechat_connect_mobile_app_secret_configured
|
||||||
|
? localText(
|
||||||
|
'密钥已配置,留空以保留当前值。',
|
||||||
|
'Secret configured. Leave empty to keep the current value.',
|
||||||
|
)
|
||||||
|
: localText(
|
||||||
|
'移动应用 AppSecret',
|
||||||
|
'Mobile App Secret',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
form.wechat_connect_open_enabled &&
|
||||||
|
(form.wechat_connect_mp_enabled ||
|
||||||
|
form.wechat_connect_mobile_enabled)
|
||||||
|
"
|
||||||
|
class="rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700 dark:border-amber-900/40 dark:bg-amber-900/10 dark:text-amber-300"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
localText(
|
||||||
|
"如果同时启用 PC 应用和公众号/移动应用,这些应用需要挂在同一个微信开放平台主体下,否则 UnionID 无法稳定归并账号。",
|
||||||
|
"When PC App is enabled together with Official Account or Mobile App, they should belong to the same WeChat Open Platform account so UnionID can merge identities reliably.",
|
||||||
|
)
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||||
<div class="space-y-3">
|
|
||||||
<label
|
|
||||||
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
||||||
>
|
|
||||||
{{ t("admin.settings.wechatConnect.modeLabel") }}
|
|
||||||
</label>
|
|
||||||
<div
|
|
||||||
class="flex items-center justify-between rounded border border-gray-200 px-4 py-3 dark:border-dark-700"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<div class="font-medium text-gray-900 dark:text-white">
|
|
||||||
{{ t("admin.settings.wechatConnect.openModeLabel") }}
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
class="mt-0.5 text-xs text-gray-500 dark:text-gray-400"
|
|
||||||
>
|
|
||||||
{{ t("admin.settings.wechatConnect.openModeHint") }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Toggle
|
|
||||||
v-model="form.wechat_connect_open_enabled"
|
|
||||||
data-testid="wechat-connect-open-enabled"
|
|
||||||
@update:model-value="syncWeChatConnectMode"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex items-center justify-between rounded border border-gray-200 px-4 py-3 dark:border-dark-700"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<div class="font-medium text-gray-900 dark:text-white">
|
|
||||||
{{ t("admin.settings.wechatConnect.mpModeLabel") }}
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
class="mt-0.5 text-xs text-gray-500 dark:text-gray-400"
|
|
||||||
>
|
|
||||||
{{ t("admin.settings.wechatConnect.mpModeHint") }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Toggle
|
|
||||||
v-model="form.wechat_connect_mp_enabled"
|
|
||||||
data-testid="wechat-connect-mp-enabled"
|
|
||||||
@update:model-value="syncWeChatConnectMode"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||||
>
|
>
|
||||||
{{ t("admin.settings.wechatConnect.redirectUrlLabel") }}
|
{{
|
||||||
|
localText(
|
||||||
|
"浏览器回调地址",
|
||||||
|
"Browser Redirect URL",
|
||||||
|
)
|
||||||
|
}}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
data-testid="wechat-connect-redirect-url"
|
data-testid="wechat-connect-redirect-url"
|
||||||
@@ -1501,6 +1653,14 @@
|
|||||||
class="input font-mono text-sm"
|
class="input font-mono text-sm"
|
||||||
:placeholder="t('admin.settings.wechatConnect.redirectUrlPlaceholder')"
|
:placeholder="t('admin.settings.wechatConnect.redirectUrlPlaceholder')"
|
||||||
/>
|
/>
|
||||||
|
<p class="mt-1.5 text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
{{
|
||||||
|
localText(
|
||||||
|
"用于 PC 应用和公众号的网页回调。移动应用走原生 SDK 时不直接使用这个浏览器回调。",
|
||||||
|
"Used by PC App and Official Account browser callbacks. Native mobile SDK flows do not start from this browser callback directly.",
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
<div
|
<div
|
||||||
class="mt-2 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3"
|
class="mt-2 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3"
|
||||||
>
|
>
|
||||||
@@ -4594,6 +4754,7 @@ import type {
|
|||||||
SystemSettings,
|
SystemSettings,
|
||||||
UpdateSettingsRequest,
|
UpdateSettingsRequest,
|
||||||
DefaultSubscriptionSetting,
|
DefaultSubscriptionSetting,
|
||||||
|
WeChatConnectMode,
|
||||||
WebSearchEmulationConfig,
|
WebSearchEmulationConfig,
|
||||||
WebSearchProviderConfig,
|
WebSearchProviderConfig,
|
||||||
WebSearchTestResult,
|
WebSearchTestResult,
|
||||||
@@ -4731,14 +4892,20 @@ interface DefaultSubscriptionGroupOption {
|
|||||||
|
|
||||||
type SettingsForm = Omit<
|
type SettingsForm = Omit<
|
||||||
SystemSettings,
|
SystemSettings,
|
||||||
"wechat_connect_open_enabled" | "wechat_connect_mp_enabled"
|
| "wechat_connect_open_enabled"
|
||||||
|
| "wechat_connect_mp_enabled"
|
||||||
|
| "wechat_connect_mobile_enabled"
|
||||||
> & {
|
> & {
|
||||||
smtp_password: string;
|
smtp_password: string;
|
||||||
turnstile_secret_key: string;
|
turnstile_secret_key: string;
|
||||||
linuxdo_connect_client_secret: string;
|
linuxdo_connect_client_secret: string;
|
||||||
wechat_connect_app_secret: string;
|
wechat_connect_app_secret: string;
|
||||||
|
wechat_connect_open_app_secret: string;
|
||||||
|
wechat_connect_mp_app_secret: string;
|
||||||
|
wechat_connect_mobile_app_secret: string;
|
||||||
wechat_connect_open_enabled: boolean;
|
wechat_connect_open_enabled: boolean;
|
||||||
wechat_connect_mp_enabled: boolean;
|
wechat_connect_mp_enabled: boolean;
|
||||||
|
wechat_connect_mobile_enabled: boolean;
|
||||||
oidc_connect_client_secret: string;
|
oidc_connect_client_secret: string;
|
||||||
force_email_on_third_party_signup: boolean;
|
force_email_on_third_party_signup: boolean;
|
||||||
payment_visible_method_alipay_source: string;
|
payment_visible_method_alipay_source: string;
|
||||||
@@ -4833,8 +5000,18 @@ const form = reactive<SettingsForm>({
|
|||||||
wechat_connect_app_id: "",
|
wechat_connect_app_id: "",
|
||||||
wechat_connect_app_secret: "",
|
wechat_connect_app_secret: "",
|
||||||
wechat_connect_app_secret_configured: false,
|
wechat_connect_app_secret_configured: false,
|
||||||
|
wechat_connect_open_app_id: "",
|
||||||
|
wechat_connect_open_app_secret: "",
|
||||||
|
wechat_connect_open_app_secret_configured: false,
|
||||||
|
wechat_connect_mp_app_id: "",
|
||||||
|
wechat_connect_mp_app_secret: "",
|
||||||
|
wechat_connect_mp_app_secret_configured: false,
|
||||||
|
wechat_connect_mobile_app_id: "",
|
||||||
|
wechat_connect_mobile_app_secret: "",
|
||||||
|
wechat_connect_mobile_app_secret_configured: false,
|
||||||
wechat_connect_open_enabled: false,
|
wechat_connect_open_enabled: false,
|
||||||
wechat_connect_mp_enabled: false,
|
wechat_connect_mp_enabled: false,
|
||||||
|
wechat_connect_mobile_enabled: false,
|
||||||
wechat_connect_mode: "open",
|
wechat_connect_mode: "open",
|
||||||
wechat_connect_scopes: "snsapi_login",
|
wechat_connect_scopes: "snsapi_login",
|
||||||
wechat_connect_redirect_url: "",
|
wechat_connect_redirect_url: "",
|
||||||
@@ -5315,17 +5492,28 @@ const wechatRedirectUrlSuggestion = computed(() => {
|
|||||||
return `${origin}/api/v1/auth/oauth/wechat/callback`;
|
return `${origin}/api/v1/auth/oauth/wechat/callback`;
|
||||||
});
|
});
|
||||||
|
|
||||||
function syncWeChatConnectMode() {
|
function syncWeChatConnectMode(preferredMode?: WeChatConnectMode) {
|
||||||
|
if (form.wechat_connect_mp_enabled && form.wechat_connect_mobile_enabled) {
|
||||||
|
if (preferredMode === "mobile") {
|
||||||
|
form.wechat_connect_mp_enabled = false;
|
||||||
|
} else {
|
||||||
|
form.wechat_connect_mobile_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const capabilities = resolveWeChatConnectModeCapabilities(
|
const capabilities = resolveWeChatConnectModeCapabilities(
|
||||||
form.wechat_connect_open_enabled,
|
form.wechat_connect_open_enabled,
|
||||||
form.wechat_connect_mp_enabled,
|
form.wechat_connect_mp_enabled,
|
||||||
|
form.wechat_connect_mobile_enabled,
|
||||||
form.wechat_connect_mode,
|
form.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
form.wechat_connect_open_enabled = capabilities.openEnabled;
|
form.wechat_connect_open_enabled = capabilities.openEnabled;
|
||||||
form.wechat_connect_mp_enabled = capabilities.mpEnabled;
|
form.wechat_connect_mp_enabled = capabilities.mpEnabled;
|
||||||
|
form.wechat_connect_mobile_enabled = capabilities.mobileEnabled;
|
||||||
form.wechat_connect_mode = deriveWeChatConnectStoredMode(
|
form.wechat_connect_mode = deriveWeChatConnectStoredMode(
|
||||||
capabilities.openEnabled,
|
capabilities.openEnabled,
|
||||||
capabilities.mpEnabled,
|
capabilities.mpEnabled,
|
||||||
|
capabilities.mobileEnabled,
|
||||||
form.wechat_connect_mode,
|
form.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
form.wechat_connect_scopes = defaultWeChatConnectScopesForMode(
|
form.wechat_connect_scopes = defaultWeChatConnectScopesForMode(
|
||||||
@@ -5333,6 +5521,27 @@ function syncWeChatConnectMode() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleWeChatOpenEnabledChange(value: boolean) {
|
||||||
|
form.wechat_connect_open_enabled = value;
|
||||||
|
syncWeChatConnectMode(value ? "open" : undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleWeChatMPEnabledChange(value: boolean) {
|
||||||
|
form.wechat_connect_mp_enabled = value;
|
||||||
|
if (value) {
|
||||||
|
form.wechat_connect_mobile_enabled = false;
|
||||||
|
}
|
||||||
|
syncWeChatConnectMode(value ? "mp" : undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleWeChatMobileEnabledChange(value: boolean) {
|
||||||
|
form.wechat_connect_mobile_enabled = value;
|
||||||
|
if (value) {
|
||||||
|
form.wechat_connect_mp_enabled = false;
|
||||||
|
}
|
||||||
|
syncWeChatConnectMode(value ? "mobile" : undefined);
|
||||||
|
}
|
||||||
|
|
||||||
async function setAndCopyWeChatRedirectUrl() {
|
async function setAndCopyWeChatRedirectUrl() {
|
||||||
const url = wechatRedirectUrlSuggestion.value;
|
const url = wechatRedirectUrlSuggestion.value;
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
@@ -5476,16 +5685,22 @@ async function loadSettings() {
|
|||||||
form.turnstile_secret_key = "";
|
form.turnstile_secret_key = "";
|
||||||
form.linuxdo_connect_client_secret = "";
|
form.linuxdo_connect_client_secret = "";
|
||||||
form.wechat_connect_app_secret = "";
|
form.wechat_connect_app_secret = "";
|
||||||
|
form.wechat_connect_open_app_secret = "";
|
||||||
|
form.wechat_connect_mp_app_secret = "";
|
||||||
|
form.wechat_connect_mobile_app_secret = "";
|
||||||
const wechatCapabilities = resolveWeChatConnectModeCapabilities(
|
const wechatCapabilities = resolveWeChatConnectModeCapabilities(
|
||||||
settings.wechat_connect_open_enabled,
|
settings.wechat_connect_open_enabled,
|
||||||
settings.wechat_connect_mp_enabled,
|
settings.wechat_connect_mp_enabled,
|
||||||
|
settings.wechat_connect_mobile_enabled,
|
||||||
settings.wechat_connect_mode,
|
settings.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
form.wechat_connect_open_enabled = wechatCapabilities.openEnabled;
|
form.wechat_connect_open_enabled = wechatCapabilities.openEnabled;
|
||||||
form.wechat_connect_mp_enabled = wechatCapabilities.mpEnabled;
|
form.wechat_connect_mp_enabled = wechatCapabilities.mpEnabled;
|
||||||
|
form.wechat_connect_mobile_enabled = wechatCapabilities.mobileEnabled;
|
||||||
form.wechat_connect_mode = deriveWeChatConnectStoredMode(
|
form.wechat_connect_mode = deriveWeChatConnectStoredMode(
|
||||||
wechatCapabilities.openEnabled,
|
wechatCapabilities.openEnabled,
|
||||||
wechatCapabilities.mpEnabled,
|
wechatCapabilities.mpEnabled,
|
||||||
|
wechatCapabilities.mobileEnabled,
|
||||||
settings.wechat_connect_mode,
|
settings.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
form.wechat_connect_scopes = defaultWeChatConnectScopesForMode(
|
form.wechat_connect_scopes = defaultWeChatConnectScopesForMode(
|
||||||
@@ -5649,6 +5864,16 @@ async function saveSettings() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (form.wechat_connect_mp_enabled && form.wechat_connect_mobile_enabled) {
|
||||||
|
appStore.showError(
|
||||||
|
localText(
|
||||||
|
"公众号和移动应用不能同时启用。",
|
||||||
|
"Official Account and Mobile App cannot be enabled at the same time.",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Validate URL fields — novalidate disables browser-native checks, so we validate here
|
// Validate URL fields — novalidate disables browser-native checks, so we validate here
|
||||||
const isValidHttpUrl = (url: string): boolean => {
|
const isValidHttpUrl = (url: string): boolean => {
|
||||||
if (!url) return true;
|
if (!url) return true;
|
||||||
@@ -5666,6 +5891,7 @@ async function saveSettings() {
|
|||||||
const wechatStoredMode = deriveWeChatConnectStoredMode(
|
const wechatStoredMode = deriveWeChatConnectStoredMode(
|
||||||
form.wechat_connect_open_enabled,
|
form.wechat_connect_open_enabled,
|
||||||
form.wechat_connect_mp_enabled,
|
form.wechat_connect_mp_enabled,
|
||||||
|
form.wechat_connect_mobile_enabled,
|
||||||
form.wechat_connect_mode,
|
form.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -5714,10 +5940,24 @@ async function saveSettings() {
|
|||||||
form.linuxdo_connect_client_secret || undefined,
|
form.linuxdo_connect_client_secret || undefined,
|
||||||
linuxdo_connect_redirect_url: form.linuxdo_connect_redirect_url,
|
linuxdo_connect_redirect_url: form.linuxdo_connect_redirect_url,
|
||||||
wechat_connect_enabled: form.wechat_connect_enabled,
|
wechat_connect_enabled: form.wechat_connect_enabled,
|
||||||
wechat_connect_app_id: form.wechat_connect_app_id,
|
wechat_connect_app_id:
|
||||||
|
form.wechat_connect_open_app_id ||
|
||||||
|
form.wechat_connect_mp_app_id ||
|
||||||
|
form.wechat_connect_mobile_app_id ||
|
||||||
|
form.wechat_connect_app_id,
|
||||||
wechat_connect_app_secret: form.wechat_connect_app_secret || undefined,
|
wechat_connect_app_secret: form.wechat_connect_app_secret || undefined,
|
||||||
|
wechat_connect_open_app_id: form.wechat_connect_open_app_id,
|
||||||
|
wechat_connect_open_app_secret:
|
||||||
|
form.wechat_connect_open_app_secret || undefined,
|
||||||
|
wechat_connect_mp_app_id: form.wechat_connect_mp_app_id,
|
||||||
|
wechat_connect_mp_app_secret:
|
||||||
|
form.wechat_connect_mp_app_secret || undefined,
|
||||||
|
wechat_connect_mobile_app_id: form.wechat_connect_mobile_app_id,
|
||||||
|
wechat_connect_mobile_app_secret:
|
||||||
|
form.wechat_connect_mobile_app_secret || undefined,
|
||||||
wechat_connect_open_enabled: form.wechat_connect_open_enabled,
|
wechat_connect_open_enabled: form.wechat_connect_open_enabled,
|
||||||
wechat_connect_mp_enabled: form.wechat_connect_mp_enabled,
|
wechat_connect_mp_enabled: form.wechat_connect_mp_enabled,
|
||||||
|
wechat_connect_mobile_enabled: form.wechat_connect_mobile_enabled,
|
||||||
wechat_connect_mode: wechatStoredMode,
|
wechat_connect_mode: wechatStoredMode,
|
||||||
wechat_connect_scopes:
|
wechat_connect_scopes:
|
||||||
defaultWeChatConnectScopesForMode(wechatStoredMode),
|
defaultWeChatConnectScopesForMode(wechatStoredMode),
|
||||||
@@ -5847,16 +6087,23 @@ async function saveSettings() {
|
|||||||
form.turnstile_secret_key = "";
|
form.turnstile_secret_key = "";
|
||||||
form.linuxdo_connect_client_secret = "";
|
form.linuxdo_connect_client_secret = "";
|
||||||
form.wechat_connect_app_secret = "";
|
form.wechat_connect_app_secret = "";
|
||||||
|
form.wechat_connect_open_app_secret = "";
|
||||||
|
form.wechat_connect_mp_app_secret = "";
|
||||||
|
form.wechat_connect_mobile_app_secret = "";
|
||||||
const updatedWechatCapabilities = resolveWeChatConnectModeCapabilities(
|
const updatedWechatCapabilities = resolveWeChatConnectModeCapabilities(
|
||||||
updated.wechat_connect_open_enabled,
|
updated.wechat_connect_open_enabled,
|
||||||
updated.wechat_connect_mp_enabled,
|
updated.wechat_connect_mp_enabled,
|
||||||
|
updated.wechat_connect_mobile_enabled,
|
||||||
updated.wechat_connect_mode,
|
updated.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
form.wechat_connect_open_enabled = updatedWechatCapabilities.openEnabled;
|
form.wechat_connect_open_enabled = updatedWechatCapabilities.openEnabled;
|
||||||
form.wechat_connect_mp_enabled = updatedWechatCapabilities.mpEnabled;
|
form.wechat_connect_mp_enabled = updatedWechatCapabilities.mpEnabled;
|
||||||
|
form.wechat_connect_mobile_enabled =
|
||||||
|
updatedWechatCapabilities.mobileEnabled;
|
||||||
form.wechat_connect_mode = deriveWeChatConnectStoredMode(
|
form.wechat_connect_mode = deriveWeChatConnectStoredMode(
|
||||||
updatedWechatCapabilities.openEnabled,
|
updatedWechatCapabilities.openEnabled,
|
||||||
updatedWechatCapabilities.mpEnabled,
|
updatedWechatCapabilities.mpEnabled,
|
||||||
|
updatedWechatCapabilities.mobileEnabled,
|
||||||
updated.wechat_connect_mode,
|
updated.wechat_connect_mode,
|
||||||
);
|
);
|
||||||
form.wechat_connect_scopes = defaultWeChatConnectScopesForMode(
|
form.wechat_connect_scopes = defaultWeChatConnectScopesForMode(
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ import TotpLoginModal from '@/components/auth/TotpLoginModal.vue'
|
|||||||
import Icon from '@/components/icons/Icon.vue'
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
import TurnstileWidget from '@/components/TurnstileWidget.vue'
|
import TurnstileWidget from '@/components/TurnstileWidget.vue'
|
||||||
import { useAuthStore, useAppStore } from '@/stores'
|
import { useAuthStore, useAppStore } from '@/stores'
|
||||||
import { getPublicSettings, isTotp2FARequired } from '@/api/auth'
|
import { getPublicSettings, isTotp2FARequired, isWeChatWebOAuthEnabled } from '@/api/auth'
|
||||||
import type { TotpLoginResponse } from '@/types'
|
import type { TotpLoginResponse } from '@/types'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -258,7 +258,7 @@ onMounted(async () => {
|
|||||||
turnstileEnabled.value = settings.turnstile_enabled
|
turnstileEnabled.value = settings.turnstile_enabled
|
||||||
turnstileSiteKey.value = settings.turnstile_site_key || ''
|
turnstileSiteKey.value = settings.turnstile_site_key || ''
|
||||||
linuxdoOAuthEnabled.value = settings.linuxdo_oauth_enabled
|
linuxdoOAuthEnabled.value = settings.linuxdo_oauth_enabled
|
||||||
wechatOAuthEnabled.value = settings.wechat_oauth_enabled
|
wechatOAuthEnabled.value = isWeChatWebOAuthEnabled(settings)
|
||||||
backendModeEnabled.value = settings.backend_mode_enabled
|
backendModeEnabled.value = settings.backend_mode_enabled
|
||||||
oidcOAuthEnabled.value = settings.oidc_oauth_enabled
|
oidcOAuthEnabled.value = settings.oidc_oauth_enabled
|
||||||
oidcOAuthProviderName.value = settings.oidc_oauth_provider_name || 'OIDC'
|
oidcOAuthProviderName.value = settings.oidc_oauth_provider_name || 'OIDC'
|
||||||
|
|||||||
@@ -282,7 +282,12 @@ import WechatOAuthSection from '@/components/auth/WechatOAuthSection.vue'
|
|||||||
import Icon from '@/components/icons/Icon.vue'
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
import TurnstileWidget from '@/components/TurnstileWidget.vue'
|
import TurnstileWidget from '@/components/TurnstileWidget.vue'
|
||||||
import { useAuthStore, useAppStore } from '@/stores'
|
import { useAuthStore, useAppStore } from '@/stores'
|
||||||
import { getPublicSettings, validatePromoCode, validateInvitationCode } from '@/api/auth'
|
import {
|
||||||
|
getPublicSettings,
|
||||||
|
isWeChatWebOAuthEnabled,
|
||||||
|
validatePromoCode,
|
||||||
|
validateInvitationCode
|
||||||
|
} from '@/api/auth'
|
||||||
import { buildAuthErrorMessage } from '@/utils/authError'
|
import { buildAuthErrorMessage } from '@/utils/authError'
|
||||||
import {
|
import {
|
||||||
isRegistrationEmailSuffixAllowed,
|
isRegistrationEmailSuffixAllowed,
|
||||||
@@ -385,7 +390,7 @@ onMounted(async () => {
|
|||||||
turnstileSiteKey.value = settings.turnstile_site_key || ''
|
turnstileSiteKey.value = settings.turnstile_site_key || ''
|
||||||
siteName.value = settings.site_name || 'Sub2API'
|
siteName.value = settings.site_name || 'Sub2API'
|
||||||
linuxdoOAuthEnabled.value = settings.linuxdo_oauth_enabled
|
linuxdoOAuthEnabled.value = settings.linuxdo_oauth_enabled
|
||||||
wechatOAuthEnabled.value = settings.wechat_oauth_enabled
|
wechatOAuthEnabled.value = isWeChatWebOAuthEnabled(settings)
|
||||||
oidcOAuthEnabled.value = settings.oidc_oauth_enabled
|
oidcOAuthEnabled.value = settings.oidc_oauth_enabled
|
||||||
oidcOAuthProviderName.value = settings.oidc_oauth_provider_name || 'OIDC'
|
oidcOAuthProviderName.value = settings.oidc_oauth_provider_name || 'OIDC'
|
||||||
registrationEmailSuffixWhitelist.value = normalizeRegistrationEmailSuffixWhitelist(
|
registrationEmailSuffixWhitelist.value = normalizeRegistrationEmailSuffixWhitelist(
|
||||||
|
|||||||
@@ -504,6 +504,8 @@ function resolveWeChatOAuthUnavailableMessage(): string {
|
|||||||
return t('auth.oauthFlow.wechatSystemBrowserOnly')
|
return t('auth.oauthFlow.wechatSystemBrowserOnly')
|
||||||
case 'wechat_browser_required':
|
case 'wechat_browser_required':
|
||||||
return t('auth.oauthFlow.wechatBrowserOnly')
|
return t('auth.oauthFlow.wechatBrowserOnly')
|
||||||
|
case 'native_app_required':
|
||||||
|
return 'This WeChat sign-in flow is only available from the native mobile app.'
|
||||||
case 'not_configured':
|
case 'not_configured':
|
||||||
return t('auth.oauthFlow.wechatNotConfigured')
|
return t('auth.oauthFlow.wechatNotConfigured')
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user