expo-duooomi-app/lib/auth.ts

136 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'reflect-metadata'
import { expoClient } from '@better-auth/expo/client'
import { createSkerClientPlugin } from '@repo/sdk'
import {
adminClient,
emailOTPClient,
genericOAuthClient,
jwtClient,
organizationClient,
phoneNumberClient,
usernameClient,
} from 'better-auth/client/plugins'
import { createAuthClient } from 'better-auth/react'
import { fetchWithLogger } from './fetch-logger'
import type { Subscription } from './plugins/stripe'
import { stripeClient } from './plugins/stripe-plugin'
import { storage } from './storage'
import type { ApiError } from './types'
const OWNER_ID = process.env.EXPO_PUBLIC_OWNER_ID
export interface CreditBalance {
tokenUsage: number
remainingTokenBalance: number
currentCreditBalance: number
unitPrice: number
}
export interface SubscriptionListItem extends Subscription {
type?: 'metered' | 'licenced'
limits?: Record<string, number>
creditBalance?: CreditBalance
highestTierPlan?: string
highestTierCredits?: number
}
export interface SubscriptionListParams {
query?: {
referenceId?: string
}
}
export interface SubscriptionRestoreParams {
referenceId?: string
subscriptionId?: string
}
export interface SubscriptionRestoreResponse {
success: boolean
subscription: {
id: string
stripeSubscriptionId: string
cancelAtPeriodEnd: boolean
periodEnd?: Date
status: string
}
}
export interface BillingPortalParams {
locale?: string
referenceId?: string
returnUrl?: string
}
export interface BillingPortalResponse {
url: string
redirect: boolean
}
export interface ISubscription {
list: (params?: SubscriptionListParams) => Promise<{ data?: SubscriptionListItem[]; error?: ApiError }>
restore: (params?: SubscriptionRestoreParams) => Promise<{ data?: SubscriptionRestoreResponse; error?: ApiError }>
billingPortal: (params?: BillingPortalParams) => Promise<{ data?: BillingPortalResponse; error?: ApiError }>
}
export const getAuthToken = async () => (await storage.getItem('bestaibest.better-auth.session_token')) || ''
export const setAuthToken = async (token: string) => {
await storage.setItem(`bestaibest.better-auth.session_token`, token)
}
export const authClient = createAuthClient({
baseURL: 'https://api.mixvideo.bowong.cc',
trustedOrigins: ['duooomi://', 'https://api.mixvideo.bowong.cc'],
storage,
scheme: 'duooomi',
fetchOptions: {
headers: {
'x-ownerid': OWNER_ID,
},
auth: {
type: 'Bearer',
token: async () => {
const Authorization = await getAuthToken()
return Authorization
},
},
customFetchImpl: fetchWithLogger as typeof fetch,
},
plugins: [
createSkerClientPlugin(),
stripeClient(),
usernameClient(),
phoneNumberClient(),
emailOTPClient(),
genericOAuthClient(),
jwtClient(),
adminClient(),
organizationClient(),
expoClient({
storage: storage as any,
}),
],
})
export const {
signIn,
signUp,
signOut,
useSession,
$Infer,
admin,
forgetPassword,
resetPassword,
emailOtp,
phoneNumber,
} = authClient
// TODO: 手机号验证码发送接口还未实现
// 需要后端提供手机号验证码发送接口,类似于 emailOtp.sendVerificationOtp
// 预期接口phoneOtp.sendVerificationOtp({ phone, type: 'phone-verification' })
// 当前在 app/auth.tsx 中的 handleSendCode 函数中使用了临时模拟代码,需要替换为真实 API 调用
export const subscription: ISubscription = Reflect.get(authClient, 'subscription')