fix: clarify wechat existing account binding

This commit is contained in:
IanShaw027
2026-04-20 22:54:47 +08:00
parent 7fdede579a
commit e1a28848fa
2 changed files with 37 additions and 2 deletions

View File

@@ -116,11 +116,16 @@
{{ t('auth.alreadyHaveAccount') }} {{ t('auth.alreadyHaveAccount') }}
</p> </p>
<p class="text-xs text-gray-500 dark:text-dark-400"> <p class="text-xs text-gray-500 dark:text-dark-400">
Sign in to an existing account, then bind this WeChat identity to it. {{
hasCurrentAuthToken
? 'Bind this WeChat identity to the account currently signed in on this browser.'
: 'Sign in to an existing account, then bind this WeChat identity to it.'
}}
</p> </p>
</div> </div>
<input <input
v-if="!hasCurrentAuthToken"
v-model="existingAccountEmail" v-model="existingAccountEmail"
data-testid="existing-account-email" data-testid="existing-account-email"
type="email" type="email"
@@ -136,7 +141,7 @@
:disabled="isSubmitting" :disabled="isSubmitting"
@click="handleExistingAccountBinding" @click="handleExistingAccountBinding"
> >
{{ t('auth.signIn') }} {{ hasCurrentAuthToken ? 'Bind current account' : t('auth.signIn') }}
</button> </button>
</div> </div>
</div> </div>
@@ -353,6 +358,7 @@ const bindSuccessMessage = t('profile.authBindings.bindSuccess')
const providerName = 'WeChat' const providerName = 'WeChat'
const needsCreateAccount = computed(() => pendingAccountAction.value === 'create_account') const needsCreateAccount = computed(() => pendingAccountAction.value === 'create_account')
const needsBindLogin = computed(() => pendingAccountAction.value === 'bind_login') const needsBindLogin = computed(() => pendingAccountAction.value === 'bind_login')
const hasCurrentAuthToken = computed(() => Boolean(getAuthToken()))
type PendingWeChatCompletion = PendingOAuthExchangeResponse & { type PendingWeChatCompletion = PendingOAuthExchangeResponse & {
step?: string step?: string

View File

@@ -345,6 +345,35 @@ describe('WechatCallbackView', () => {
expect(replaceMock.mock.calls[0]?.[0]).toContain('mode%3Dopen') expect(replaceMock.mock.calls[0]?.[0]).toContain('mode%3Dopen')
}) })
it('binds directly to the current signed-in account during invitation flow', async () => {
exchangePendingOAuthCompletionMock.mockResolvedValue({
error: 'invitation_required',
redirect: '/usage',
})
getAuthTokenMock.mockReturnValue('current-auth-token')
const wrapper = mount(WechatCallbackView, {
global: {
stubs: {
AuthLayout: { template: '<div><slot /></div>' },
Icon: true,
RouterLink: { template: '<a><slot /></a>' },
transition: false,
},
},
})
await flushPromises()
expect(wrapper.find('[data-testid="existing-account-email"]').exists()).toBe(false)
await wrapper.get('[data-testid="existing-account-submit"]').trigger('click')
expect(prepareOAuthBindAccessTokenCookieMock).toHaveBeenCalledTimes(1)
expect(locationState.current.href).toContain('intent=bind_current_user')
expect(locationState.current.href).toContain('redirect=%2Fusage')
expect(locationState.current.href).toContain('mode=open')
})
it('collects email for pending oauth account creation and submits adoption decisions', async () => { it('collects email for pending oauth account creation and submits adoption decisions', async () => {
exchangePendingOAuthCompletionMock.mockResolvedValue({ exchangePendingOAuthCompletionMock.mockResolvedValue({
error: 'email_required', error: 'email_required',