150 lines
4.5 KiB
TypeScript
150 lines
4.5 KiB
TypeScript
import { prisma } from "@/lib/prisma"
|
|
import { XMLParser } from "fast-xml-parser"
|
|
|
|
let lastSyncTime: number | null = null
|
|
const SYNC_INTERVAL = 60 * 60 * 1000 // 1h
|
|
|
|
async function fetchNextcloudUsers() {
|
|
const nextcloudUsername = process.env.NEXTCLOUD_ADMIN_USERNAME
|
|
const nextcloudPassword = process.env.NEXTCLOUD_ADMIN_PASSWORD
|
|
const nextcloudUrl = process.env.NEXTCLOUD_URL
|
|
|
|
if (!nextcloudUsername || !nextcloudPassword || !nextcloudUrl) {
|
|
throw new Error("[!] Missing Nextcloud credentials or URL")
|
|
}
|
|
|
|
const basicAuth = Buffer.from(`${nextcloudUsername}:${nextcloudPassword}`).toString('base64')
|
|
|
|
const response = await fetch(`${nextcloudUrl}/ocs/v2.php/cloud/users`, {
|
|
headers: {
|
|
"Authorization": `Basic ${basicAuth}`,
|
|
"OCS-APIRequest": "true"
|
|
}
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`[!] Failed to fetch Nextcloud users: ${response.statusText}`)
|
|
}
|
|
|
|
const xmlText = await response.text()
|
|
const parser = new XMLParser()
|
|
const result = parser.parse(xmlText)
|
|
|
|
const users = result.ocs.data.users.element || []
|
|
return Array.isArray(users) ? users : [users]
|
|
}
|
|
|
|
async function fetchNextcloudUserDetails(userId: string) {
|
|
const nextcloudUsername = process.env.NEXTCLOUD_ADMIN_USERNAME
|
|
const nextcloudPassword = process.env.NEXTCLOUD_ADMIN_PASSWORD
|
|
const nextcloudUrl = process.env.NEXTCLOUD_URL
|
|
|
|
if (!nextcloudUsername || !nextcloudPassword || !nextcloudUrl) {
|
|
throw new Error("[!] Missing Nextcloud credentials or URL")
|
|
}
|
|
|
|
const basicAuth = Buffer.from(`${nextcloudUsername}:${nextcloudPassword}`).toString('base64')
|
|
|
|
const response = await fetch(`${nextcloudUrl}/ocs/v2.php/cloud/users/${userId}`, {
|
|
headers: {
|
|
"Authorization": `Basic ${basicAuth}`,
|
|
"OCS-APIRequest": "true"
|
|
}
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`[!] Failed to fetch Nextcloud user details: ${response.statusText}`)
|
|
}
|
|
|
|
const xmlText = await response.text()
|
|
const parser = new XMLParser()
|
|
const result = parser.parse(xmlText)
|
|
|
|
return result.ocs.data
|
|
}
|
|
|
|
export async function syncUserWithNextcloud(email: string, bypassCache: boolean = false): Promise<string | null> {
|
|
try {
|
|
const now = Date.now()
|
|
if (lastSyncTime === null || now - lastSyncTime > SYNC_INTERVAL || bypassCache) {
|
|
await syncAllNextcloudUsers()
|
|
lastSyncTime = now
|
|
}
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { email }
|
|
})
|
|
|
|
return user?.nextcloudId || null
|
|
} catch (error) {
|
|
console.error(`[!] Error syncing user ${email} with Nextcloud:`, error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
async function syncAllNextcloudUsers() {
|
|
try {
|
|
const nextcloudUserIds = await fetchNextcloudUsers()
|
|
|
|
for (const userId of nextcloudUserIds) {
|
|
try {
|
|
const userDetails = await fetchNextcloudUserDetails(userId)
|
|
|
|
if (!userDetails.email) {
|
|
console.log(`[i] Skipping user ${userId} - no email found`)
|
|
continue
|
|
}
|
|
|
|
await prisma.user.upsert({
|
|
where: { email: userDetails.email },
|
|
update: { nextcloudId: userId },
|
|
create: {
|
|
email: userDetails.email,
|
|
nextcloudId: userId,
|
|
username: userDetails.id
|
|
}
|
|
})
|
|
} catch (error) {
|
|
console.error(`[!] Error processing user ${userId}:`, error)
|
|
}
|
|
}
|
|
|
|
console.log("Nextcloud users synced successfully")
|
|
} catch (error) {
|
|
console.error("[!] Error syncing Nextcloud users:", error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
export async function deleteNextcloudUser(nextcloudId: string): Promise<boolean> {
|
|
try {
|
|
const nextcloudUsername = process.env.NEXTCLOUD_ADMIN_USERNAME
|
|
const nextcloudPassword = process.env.NEXTCLOUD_ADMIN_PASSWORD
|
|
const nextcloudUrl = process.env.NEXTCLOUD_URL
|
|
|
|
if (!nextcloudUsername || !nextcloudPassword || !nextcloudUrl) {
|
|
console.error("[!] Missing Nextcloud credentials or URL")
|
|
return false
|
|
}
|
|
|
|
const basicAuth = Buffer.from(`${nextcloudUsername}:${nextcloudPassword}`).toString('base64')
|
|
|
|
const response = await fetch(`${nextcloudUrl}/ocs/v2.php/cloud/users/${nextcloudId}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
"Authorization": `Basic ${basicAuth}`,
|
|
"OCS-APIRequest": "true"
|
|
}
|
|
})
|
|
|
|
if (!response.ok) {
|
|
console.error(`[!] Failed to delete Nextcloud user: ${response.statusText} (${response.status})`)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
} catch (error) {
|
|
console.error(`[!] Error deleting Nextcloud user ${nextcloudId}:`, error)
|
|
return false
|
|
}
|
|
} |