2025-04-08 11:21:58 +08:00
|
|
|
'use server'
|
|
|
|
|
import {cookies} from 'next/headers'
|
2025-04-23 19:00:53 +08:00
|
|
|
import {ApiResponse, UnauthorizedError} from '@/lib/api'
|
2025-04-08 11:21:58 +08:00
|
|
|
import {AuthContext} from '@/lib/auth'
|
|
|
|
|
import {User} from '@/lib/models'
|
2025-04-23 19:00:53 +08:00
|
|
|
import {callByDevice, callByUser, callPublic, getUserToken} from '@/actions/base'
|
2025-04-18 17:48:12 +08:00
|
|
|
import {redirect} from 'next/navigation'
|
2025-04-23 19:00:53 +08:00
|
|
|
import {cache} from 'react'
|
2025-04-08 11:21:58 +08:00
|
|
|
|
|
|
|
|
export interface LoginParams {
|
|
|
|
|
username: string
|
|
|
|
|
password: string
|
2025-04-23 19:00:53 +08:00
|
|
|
remember: boolean
|
2025-04-08 11:21:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type LoginResp = {
|
|
|
|
|
access_token: string
|
|
|
|
|
refresh_token: string
|
2025-04-23 19:00:53 +08:00
|
|
|
expires_in: number
|
|
|
|
|
token_type: string
|
|
|
|
|
scope?: string
|
2025-04-08 11:21:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function login(props: LoginParams): Promise<ApiResponse> {
|
|
|
|
|
// 尝试登录
|
2025-04-23 19:00:53 +08:00
|
|
|
const result = await callByDevice<LoginResp>('/api/auth/token', {
|
|
|
|
|
...props,
|
|
|
|
|
grant_type: 'password',
|
|
|
|
|
login_type: 'phone_code',
|
2025-04-08 11:21:58 +08:00
|
|
|
})
|
|
|
|
|
if (!result.success) {
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存到 cookies
|
2025-04-23 19:00:53 +08:00
|
|
|
const data = result.data
|
2025-04-08 11:21:58 +08:00
|
|
|
const cookieStore = await cookies()
|
|
|
|
|
cookieStore.set('auth_token', data.access_token, {
|
|
|
|
|
httpOnly: true,
|
|
|
|
|
sameSite: 'strict',
|
2025-04-23 19:00:53 +08:00
|
|
|
maxAge: Math.max(data.expires_in, 0),
|
2025-04-08 11:21:58 +08:00
|
|
|
})
|
|
|
|
|
cookieStore.set('auth_refresh', data.refresh_token, {
|
|
|
|
|
httpOnly: true,
|
|
|
|
|
sameSite: 'strict',
|
|
|
|
|
})
|
2025-04-23 19:00:53 +08:00
|
|
|
// cookieStore.set('auth_info', JSON.stringify(data.auth), {
|
|
|
|
|
// httpOnly: true,
|
|
|
|
|
// sameSite: 'strict',
|
|
|
|
|
// })
|
|
|
|
|
// cookieStore.set('auth_profile', JSON.stringify(data.profile), {
|
|
|
|
|
// httpOnly: true,
|
|
|
|
|
// sameSite: 'strict',
|
|
|
|
|
// })
|
2025-04-08 11:21:58 +08:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
data: undefined,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 17:48:12 +08:00
|
|
|
export async function logout() {
|
|
|
|
|
const cookieStore = await cookies()
|
|
|
|
|
|
|
|
|
|
// 尝试删除后台会话
|
|
|
|
|
const access_token = cookieStore.get('auth_token')?.value
|
|
|
|
|
const refresh_token = cookieStore.get('auth_refresh')?.value
|
|
|
|
|
if (access_token && refresh_token) {
|
2025-04-24 10:46:48 +08:00
|
|
|
await callByDevice('/api/auth/revoke', {
|
2025-04-18 17:48:12 +08:00
|
|
|
access_token,
|
|
|
|
|
refresh_token,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除 cookies
|
|
|
|
|
cookieStore.set('auth_token', '', {
|
|
|
|
|
httpOnly: true,
|
|
|
|
|
sameSite: 'strict',
|
|
|
|
|
maxAge: -1,
|
|
|
|
|
})
|
|
|
|
|
cookieStore.set('auth_refresh', '', {
|
|
|
|
|
httpOnly: true,
|
|
|
|
|
sameSite: 'strict',
|
|
|
|
|
maxAge: -1,
|
|
|
|
|
})
|
|
|
|
|
|
2025-04-23 19:00:53 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
data: undefined,
|
|
|
|
|
}
|
2025-04-18 17:48:12 +08:00
|
|
|
}
|
|
|
|
|
|
2025-04-23 19:00:53 +08:00
|
|
|
export async function getProfile() {
|
|
|
|
|
try {
|
|
|
|
|
const token = await getUserToken()
|
|
|
|
|
const result = await callPublic<User>('/api/user/get/token', {token})
|
2025-04-08 11:21:58 +08:00
|
|
|
|
2025-04-23 19:00:53 +08:00
|
|
|
if (!result.success) {
|
|
|
|
|
throw new Error('获取用户信息失败')
|
2025-04-08 11:21:58 +08:00
|
|
|
}
|
2025-04-23 19:00:53 +08:00
|
|
|
return result.data
|
2025-04-08 11:21:58 +08:00
|
|
|
}
|
|
|
|
|
catch (e) {
|
2025-04-23 19:00:53 +08:00
|
|
|
if (e === UnauthorizedError) {
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
throw e
|
2025-04-08 11:21:58 +08:00
|
|
|
}
|
|
|
|
|
}
|