feat(auth): add account linking support for different email providers

This commit is contained in:
RainbowBird
2026-06-09 17:46:51 +08:00
parent 11b820a77f
commit 2ac4e90d56
3 changed files with 61 additions and 0 deletions
@@ -0,0 +1,55 @@
import { describe, expect, it, vi } from 'vitest'
import { createSSRApp, ref } from 'vue'
import { renderToString } from 'vue/server-renderer'
import { useLinkedAccounts } from './use-linked-accounts'
describe('useLinkedAccounts', () => {
it('passes the profile page URL as the OAuth link error callback URL', async () => {
const linkSocial = vi.fn(async () => ({
data: { status: true, redirect: false },
error: null,
}))
const holder: {
linkedAccounts?: ReturnType<typeof useLinkedAccounts>
} = {}
const app = createSSRApp({
setup() {
holder.linkedAccounts = useLinkedAccounts({
client: {
listAccounts: vi.fn(async () => ({ data: [], error: null })),
unlinkAccount: vi.fn(async () => ({ data: null, error: null })),
linkSocial,
},
isAuthenticated: ref(false),
describeError: () => '',
buildCallbackURL: () => 'https://auth.airi.build/ui/profile',
messages: {
listFailed: 'list failed',
unlinkFailed: 'unlink failed',
linkFailed: 'link failed',
lastAccount: 'last account',
unlinked: provider => `${provider} unlinked`,
linkStarted: provider => `${provider} link started`,
},
})
return () => null
},
})
await renderToString(app)
if (!holder.linkedAccounts)
throw new Error('Expected linked accounts composable to initialize')
await holder.linkedAccounts.link('github', 'GitHub')
expect(linkSocial).toHaveBeenCalledWith({
provider: 'github',
callbackURL: 'https://auth.airi.build/ui/profile',
errorCallbackURL: 'https://auth.airi.build/ui/profile',
})
})
})
@@ -196,6 +196,7 @@ export function useLinkedAccounts(args: UseLinkedAccountsArgs) {
const { data, error: apiError } = await args.client.linkSocial({
provider: providerId,
callbackURL,
errorCallbackURL: callbackURL,
})
if (apiError)
throw new Error(apiError.message ?? 'linkSocial failed')