mirror of
https://github.com/moeru-ai/airi.git
synced 2026-08-14 08:52:42 +00:00
refactor: reconcile steam auth with merged #2226
This commit is contained in:
@@ -97,9 +97,6 @@ export function createAuthService(params: {
|
||||
signingInFlight = true
|
||||
|
||||
try {
|
||||
// Clean up any previous in-flight login
|
||||
closeLoopback?.()
|
||||
|
||||
const codeVerifier = generateCodeVerifier()
|
||||
const codeChallenge = await generateCodeChallenge(codeVerifier)
|
||||
const state = generateState()
|
||||
|
||||
@@ -125,7 +125,6 @@ describe('ui-server-auth sign-in flow helpers', () => {
|
||||
expect(JSON.parse(String((init as RequestInit).body))).toEqual({
|
||||
provider: 'google',
|
||||
callbackURL: 'https://api.airi.test/api/auth/oauth2/authorize?client_id=airi-stage-web',
|
||||
disableRedirect: true,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -147,7 +146,6 @@ describe('ui-server-auth sign-in flow helpers', () => {
|
||||
expect(String(url)).toBe('https://api.airi.test/api/auth/sign-in/steam')
|
||||
expect(JSON.parse(String((init as RequestInit).body))).toEqual({
|
||||
callbackURL: 'https://api.airi.test/api/auth/oauth2/authorize?client_id=airi-stage-web',
|
||||
disableRedirect: true,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -107,8 +107,8 @@ export async function requestSocialSignInRedirect(params: SocialSignInRedirectPa
|
||||
// `/sign-in/steam`, surfaced here as the typed `signIn.steam` action.
|
||||
// Other providers use the standard `/sign-in/social`.
|
||||
const result = params.provider === 'steam'
|
||||
? await client.signIn.steam({ callbackURL: params.callbackURL, disableRedirect: true })
|
||||
: await client.signIn.social({ provider: params.provider, callbackURL: params.callbackURL, disableRedirect: true })
|
||||
? await client.signIn.steam({ callbackURL: params.callbackURL })
|
||||
: await client.signIn.social({ provider: params.provider, callbackURL: params.callbackURL })
|
||||
|
||||
const url = result.data?.url
|
||||
if (typeof url === 'string')
|
||||
|
||||
@@ -7,6 +7,8 @@ import { SERVER_URL } from './server'
|
||||
const OIDC_AUTHORIZE_PATH = '/api/auth/oauth2/authorize'
|
||||
const OIDC_TOKEN_PATH = '/api/auth/oauth2/token'
|
||||
|
||||
export type SocialOAuthProvider = 'google' | 'github'
|
||||
|
||||
export interface OIDCFlowParams {
|
||||
clientId: string
|
||||
redirectUri: string
|
||||
@@ -17,7 +19,7 @@ export interface OIDCFlowParams {
|
||||
*/
|
||||
clientSecret?: string
|
||||
/** Social provider hint — skips the server-side picker page. */
|
||||
provider?: 'google' | 'github' | 'steam'
|
||||
provider?: SocialOAuthProvider
|
||||
}
|
||||
|
||||
export interface OIDCFlowState {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { OIDCFlowParams, TokenResponse } from './auth-oidc'
|
||||
import type { OIDCFlowParams, SocialOAuthProvider, TokenResponse } from './auth-oidc'
|
||||
|
||||
import { createAuthClient } from 'better-auth/vue'
|
||||
|
||||
@@ -8,7 +8,7 @@ import { buildAuthorizationURL, persistFlowState } from './auth-oidc'
|
||||
import { SERVER_URL } from './server'
|
||||
import { steamClient } from './steam-auth-client'
|
||||
|
||||
export type OAuthProvider = 'google' | 'github' | 'steam'
|
||||
export type OAuthProvider = SocialOAuthProvider | 'steam'
|
||||
|
||||
// NOTICE: reads the same localStorage key ('auth/v1/token') that useAuthStore's
|
||||
// `token` ref writes via useLocalStorage. We bypass the store here because
|
||||
@@ -194,12 +194,6 @@ export async function signInOIDC(params: OIDCFlowParams) {
|
||||
return
|
||||
}
|
||||
|
||||
if (provider === 'steam') {
|
||||
// Steam is OpenID 2.0; only the Steam plugin endpoint can start it.
|
||||
await authClient.signIn.steam({ callbackURL: url.toString() })
|
||||
return
|
||||
}
|
||||
|
||||
await authClient.signIn.social({
|
||||
provider,
|
||||
callbackURL: url.toString(),
|
||||
@@ -226,7 +220,7 @@ export async function signInOIDC(params: OIDCFlowParams) {
|
||||
* social provider. Omit to land on the project's hosted login page
|
||||
* (ui-server-auth) where the user can choose email/password or social.
|
||||
*/
|
||||
export async function triggerSignIn(opts?: { provider?: OAuthProvider }): Promise<void> {
|
||||
export async function triggerSignIn(opts?: { provider?: SocialOAuthProvider }): Promise<void> {
|
||||
await signInOIDC({
|
||||
clientId: OIDC_CLIENT_ID,
|
||||
redirectUri: OIDC_REDIRECT_URI,
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { BetterFetch } from '@better-fetch/fetch'
|
||||
export interface SteamOAuthStartArgs {
|
||||
callbackURL: string
|
||||
errorCallbackURL?: string
|
||||
disableRedirect?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { betterAuth } from 'better-auth'
|
||||
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'
|
||||
import { beforeAll, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { mockDB } from '../mock-db'
|
||||
import { steam } from './steam'
|
||||
@@ -74,8 +74,6 @@ describe('steam auth plugin', () => {
|
||||
auth = await createTestAuth()
|
||||
})
|
||||
|
||||
afterEach(() => vi.unstubAllGlobals())
|
||||
|
||||
// NOTICE:
|
||||
// We mock the module-global `fetch` for Steam's `check_authentication`
|
||||
// dumb-mode verification POST instead of hitting the real
|
||||
@@ -104,15 +102,6 @@ describe('steam auth plugin', () => {
|
||||
expect(url.searchParams.get('openid.return_to')).toContain('/steam/callback?state=')
|
||||
})
|
||||
|
||||
it('skips the automatic redirect when disableRedirect is set', async () => {
|
||||
const { response } = await auth.api.signInSteam({
|
||||
body: { callbackURL: 'http://localhost/ui/profile', disableRedirect: true },
|
||||
returnHeaders: true,
|
||||
})
|
||||
|
||||
expect(response.redirect).toBe(false)
|
||||
})
|
||||
|
||||
it('creates a user with a placeholder email on first sign-in and reuses the same account on later sign-ins', async () => {
|
||||
mockSteamVerification(true)
|
||||
const context = await auth.$context
|
||||
|
||||
@@ -23,7 +23,6 @@ const STEAM_CLAIMED_ID_PATTERN = /^https:\/\/steamcommunity\.com\/openid\/id\/(\
|
||||
const SignInBodySchema = z.object({
|
||||
callbackURL: z.string().meta({ description: 'The URL to redirect to after sign in' }),
|
||||
errorCallbackURL: z.string().meta({ description: 'The URL to redirect to if an error occurs' }).optional(),
|
||||
disableRedirect: z.boolean().optional(),
|
||||
})
|
||||
|
||||
const CallbackQuerySchema = z.looseObject({
|
||||
@@ -121,7 +120,7 @@ export function steam() {
|
||||
const { state } = await generateState(ctx, undefined, undefined)
|
||||
return ctx.json({
|
||||
url: buildOpenIdRedirectURL(ctx.context.baseURL, state),
|
||||
redirect: !ctx.body.disableRedirect,
|
||||
redirect: true,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -145,7 +144,7 @@ export function steam() {
|
||||
const { state } = await generateState(ctx, { userId: session.user.id, email: session.user.email }, undefined)
|
||||
return ctx.json({
|
||||
url: buildOpenIdRedirectURL(ctx.context.baseURL, state),
|
||||
redirect: !ctx.body.disableRedirect,
|
||||
redirect: true,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user