169 lines
4.9 KiB
TypeScript
169 lines
4.9 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { prisma } from '@/lib/prisma'
|
|
import { withCors } from '@/lib/middleware'
|
|
|
|
async function handleCredentialsPost(req: NextRequest) {
|
|
try {
|
|
const pathSegments = req.nextUrl.pathname.split('/')
|
|
const hostnameIndex = pathSegments.indexOf('hosts') + 1
|
|
const hostname = pathSegments[hostnameIndex]
|
|
|
|
if (!hostname) {
|
|
return NextResponse.json({ error: '缺少主机名' }, { status: 400 })
|
|
}
|
|
|
|
const credentialsData = await req.json()
|
|
console.log(JSON.stringify(credentialsData))
|
|
const currentTime = new Date()
|
|
|
|
if (!Array.isArray(credentialsData) || credentialsData.length < 1) {
|
|
return NextResponse.json({ error: '无效的凭据数据格式' }, { status: 400 })
|
|
}
|
|
|
|
// Extract username from the first element
|
|
const [userKey, username] = credentialsData[0]
|
|
if (userKey !== 'User' || !username) {
|
|
return NextResponse.json({ error: '无效的用户信息' }, { status: 400 })
|
|
}
|
|
|
|
// Process browser credentials
|
|
const savedCredentials = []
|
|
|
|
for (let i = 1; i < credentialsData.length; i++) {
|
|
const browserData = credentialsData[i]
|
|
|
|
if (!Array.isArray(browserData) || browserData.length < 3) {
|
|
continue
|
|
}
|
|
|
|
const [enabled, browserName, browserCredentials] = browserData
|
|
|
|
if (!enabled || !browserName || !Array.isArray(browserCredentials)) {
|
|
continue
|
|
}
|
|
|
|
// Process each credential for this browser
|
|
for (const cred of browserCredentials) {
|
|
const { URL, Login, Password } = cred
|
|
|
|
if (!URL || !Login || !Password) {
|
|
continue
|
|
}
|
|
|
|
// Try to find existing credential
|
|
const existingCredential = await prisma.credential.findUnique({
|
|
where: {
|
|
hostname_username_browser_url_login: {
|
|
hostname,
|
|
username,
|
|
browser: browserName,
|
|
url: URL,
|
|
login: Login
|
|
}
|
|
},
|
|
include: {
|
|
passwords: {
|
|
orderBy: { timestamp: 'desc' }
|
|
}
|
|
}
|
|
})
|
|
|
|
if (existingCredential) {
|
|
// Check if password is different from the latest one
|
|
const latestPassword = existingCredential.passwords[0]
|
|
|
|
// Update sync time
|
|
await prisma.credential.update({
|
|
where: { id: existingCredential.id },
|
|
data: { lastSyncTime: currentTime }
|
|
})
|
|
|
|
if (!latestPassword || latestPassword.value !== Password) {
|
|
// Add new password to history
|
|
await prisma.password.create({
|
|
data: {
|
|
credentialId: existingCredential.id,
|
|
value: Password,
|
|
timestamp: new Date()
|
|
}
|
|
})
|
|
|
|
savedCredentials.push(existingCredential)
|
|
}
|
|
} else {
|
|
// Ensure host exists first
|
|
await prisma.host.upsert({
|
|
where: { hostname },
|
|
update: {},
|
|
create: { hostname }
|
|
})
|
|
|
|
// Create new credential
|
|
const newCredential = await prisma.credential.create({
|
|
data: {
|
|
hostname,
|
|
username,
|
|
browser: browserName,
|
|
url: URL,
|
|
login: Login,
|
|
lastSyncTime: currentTime,
|
|
passwords: {
|
|
create: {
|
|
value: Password,
|
|
timestamp: new Date()
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
savedCredentials.push(newCredential)
|
|
}
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({
|
|
message: '凭据保存成功',
|
|
count: savedCredentials.length
|
|
})
|
|
|
|
} catch (error) {
|
|
console.error('保存凭据失败:', error)
|
|
return NextResponse.json({ error: '保存凭据失败' }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
async function handleCredentialsGet(req: NextRequest) {
|
|
try {
|
|
const pathSegments = req.nextUrl.pathname.split('/')
|
|
const hostnameIndex = pathSegments.indexOf('hosts') + 1
|
|
const hostname = pathSegments[hostnameIndex]
|
|
|
|
if (!hostname) {
|
|
return NextResponse.json({ error: '缺少主机名' }, { status: 400 })
|
|
}
|
|
|
|
const credentials = await prisma.credential.findMany({
|
|
where: { hostname },
|
|
include: {
|
|
passwords: {
|
|
orderBy: { timestamp: 'desc' }
|
|
}
|
|
},
|
|
orderBy: [
|
|
{ username: 'asc' },
|
|
{ browser: 'asc' },
|
|
{ url: 'asc' }
|
|
]
|
|
})
|
|
|
|
return NextResponse.json(credentials)
|
|
|
|
} catch (error) {
|
|
console.error('获取凭据失败:', error)
|
|
return NextResponse.json({ error: '获取凭据失败' }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
export const POST = withCors(handleCredentialsPost)
|
|
export const GET = withCors(handleCredentialsGet)
|