From e689d15688f9885fdae12866fb8ea57a3ed09e41 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 3 Aug 2025 12:29:12 +0800 Subject: [PATCH] :lipstick: Optimize webpage connections experience --- .../Auth/OpenId/ConnectionController.cs | 48 ++----------------- DysonNetwork.Pass/Client/src/router/index.ts | 5 ++ .../Client/src/views/accounts/security.vue | 2 +- .../Client/src/views/callback.vue | 9 ++++ 4 files changed, 20 insertions(+), 44 deletions(-) create mode 100644 DysonNetwork.Pass/Client/src/views/callback.vue diff --git a/DysonNetwork.Pass/Auth/OpenId/ConnectionController.cs b/DysonNetwork.Pass/Auth/OpenId/ConnectionController.cs index e146593..c92763d 100644 --- a/DysonNetwork.Pass/Auth/OpenId/ConnectionController.cs +++ b/DysonNetwork.Pass/Auth/OpenId/ConnectionController.cs @@ -126,43 +126,6 @@ public class ConnectionController( public string? ReturnUrl { get; set; } } - /// - /// Initiates manual connection to an OAuth provider for the current user - /// - [HttpPost("connect")] - public async Task> InitiateConnection([FromBody] ConnectProviderRequest request) - { - if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) - return Unauthorized(); - - var oidcService = GetOidcService(request.Provider); - if (oidcService == null) - return BadRequest($"Provider '{request.Provider}' is not supported"); - - var existingConnection = await db.AccountConnections - .AnyAsync(c => c.AccountId == currentUser.Id && c.Provider == oidcService.ProviderName); - - if (existingConnection) - return BadRequest($"You already have a {request.Provider} connection"); - - var state = Guid.NewGuid().ToString("N"); - var nonce = Guid.NewGuid().ToString("N"); - var stateValue = $"{currentUser.Id}|{request.Provider}|{nonce}"; - var finalReturnUrl = !string.IsNullOrEmpty(request.ReturnUrl) ? request.ReturnUrl : "/settings/connections"; - - // Store state and return URL in cache - await cache.SetAsync($"{StateCachePrefix}{state}", stateValue, StateExpiration); - await cache.SetAsync($"{ReturnUrlCachePrefix}{state}", finalReturnUrl, StateExpiration); - - var authUrl = oidcService.GetAuthorizationUrl(state, nonce); - - return Ok(new - { - authUrl, - message = $"Redirect to this URL to connect your {request.Provider} account" - }); - } - [AllowAnonymous] [Route("/auth/callback/{provider}")] [HttpGet, HttpPost] @@ -194,7 +157,7 @@ public class ConnectionController( await cache.RemoveAsync(stateKey); // Handle the flow based on state type - if (oidcState.FlowType == OidcFlowType.Connect && oidcState.AccountId.HasValue) + if (oidcState is { FlowType: OidcFlowType.Connect, AccountId: not null }) { // Connection flow if (oidcState.DeviceId != null) @@ -212,11 +175,10 @@ public class ConnectionController( } // Store return URL if provided - if (!string.IsNullOrEmpty(oidcState.ReturnUrl) && oidcState.ReturnUrl != "/") - { - var returnUrlKey = $"{ReturnUrlCachePrefix}{callbackData.State}"; - await cache.SetAsync(returnUrlKey, oidcState.ReturnUrl, StateExpiration); - } + if (string.IsNullOrEmpty(oidcState.ReturnUrl) || oidcState.ReturnUrl == "/") + return await HandleLoginOrRegistration(provider, oidcService, callbackData); + var returnUrlKey = $"{ReturnUrlCachePrefix}{callbackData.State}"; + await cache.SetAsync(returnUrlKey, oidcState.ReturnUrl, StateExpiration); return await HandleLoginOrRegistration(provider, oidcService, callbackData); } diff --git a/DysonNetwork.Pass/Client/src/router/index.ts b/DysonNetwork.Pass/Client/src/router/index.ts index aab82ee..62d10fb 100644 --- a/DysonNetwork.Pass/Client/src/router/index.ts +++ b/DysonNetwork.Pass/Client/src/router/index.ts @@ -55,6 +55,11 @@ const router = createRouter({ }, ], }, + { + path: '/auth/callback', + name: 'authCallback', + component: () => import('../views/callback.vue'), + }, { path: '/:notFound(.*)', name: 'errorNotFound', diff --git a/DysonNetwork.Pass/Client/src/views/accounts/security.vue b/DysonNetwork.Pass/Client/src/views/accounts/security.vue index f5eb885..fca76b4 100644 --- a/DysonNetwork.Pass/Client/src/views/accounts/security.vue +++ b/DysonNetwork.Pass/Client/src/views/accounts/security.vue @@ -49,7 +49,7 @@ import { NCard, NList, NListItem, NThing, NAlert } from 'naive-ui' import { computed, onMounted, ref } from 'vue' -const connectionsProviders = ['apple', 'google', 'microsoft', 'discord'] +const connectionsProviders = ['apple', 'google', 'microsoft', 'discord', 'github', 'afdian'] const connections = ref([]) const connectionsAddable = computed(() => diff --git a/DysonNetwork.Pass/Client/src/views/callback.vue b/DysonNetwork.Pass/Client/src/views/callback.vue new file mode 100644 index 0000000..f95ffc4 --- /dev/null +++ b/DysonNetwork.Pass/Client/src/views/callback.vue @@ -0,0 +1,9 @@ + + +