carnet api

This commit is contained in:
alma 2025-04-20 13:36:23 +02:00
parent 9458a0488a
commit 5950eafbe5

View File

@ -3,31 +3,73 @@ import { getServerSession } from 'next-auth';
import { authOptions } from '@/app/api/auth/[...nextauth]/route';
import { DOMParser } from '@xmldom/xmldom';
async function establishNextcloudSession(nextcloudUrl: string, keycloakToken: string) {
// First, try to establish a session with Nextcloud using the Keycloak token
const sessionResponse = await fetch(`${nextcloudUrl}/index.php/apps/oauth2/api/v1/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${keycloakToken}`,
},
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: keycloakToken,
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
client_id: process.env.NEXTCLOUD_CLIENT_ID || '',
client_secret: process.env.NEXTCLOUD_CLIENT_SECRET || '',
}).toString(),
});
// Simple in-memory cache for Nextcloud tokens
const tokenCache = new Map<string, { token: string; expires: number }>();
if (!sessionResponse.ok) {
const errorText = await sessionResponse.text();
console.error('Failed to establish Nextcloud session:', errorText);
throw new Error('Failed to establish Nextcloud session');
async function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function establishNextcloudSession(nextcloudUrl: string, keycloakToken: string, maxRetries = 3) {
// Check cache first
const cacheKey = `${nextcloudUrl}:${keycloakToken}`;
const cached = tokenCache.get(cacheKey);
if (cached && cached.expires > Date.now()) {
return cached.token;
}
const sessionData = await sessionResponse.json();
return sessionData.access_token;
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
// Add exponential backoff
if (attempt > 0) {
await sleep(Math.pow(2, attempt) * 1000);
}
const sessionResponse = await fetch(`${nextcloudUrl}/index.php/apps/oauth2/api/v1/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${keycloakToken}`,
},
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: keycloakToken,
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
client_id: process.env.NEXTCLOUD_CLIENT_ID || '',
client_secret: process.env.NEXTCLOUD_CLIENT_SECRET || '',
}).toString(),
});
if (sessionResponse.status === 429) {
// Rate limited, wait and retry
const retryAfter = sessionResponse.headers.get('Retry-After');
await sleep((retryAfter ? parseInt(retryAfter) : 5) * 1000);
continue;
}
if (!sessionResponse.ok) {
const errorText = await sessionResponse.text();
console.error('Failed to establish Nextcloud session:', errorText);
throw new Error('Failed to establish Nextcloud session');
}
const sessionData = await sessionResponse.json();
// Cache the token for 5 minutes
tokenCache.set(cacheKey, {
token: sessionData.access_token,
expires: Date.now() + 5 * 60 * 1000
});
return sessionData.access_token;
} catch (error) {
lastError = error;
console.error(`Attempt ${attempt + 1} failed:`, error);
}
}
throw lastError || new Error('Failed to establish Nextcloud session after retries');
}
export async function GET() {
@ -61,7 +103,7 @@ export async function GET() {
}
try {
// Establish Nextcloud session
// Establish Nextcloud session with retries
const nextcloudToken = await establishNextcloudSession(nextcloudUrl, session.accessToken);
// Get user's folders using WebDAV with Nextcloud token