326 lines
9.1 KiB
TypeScript
326 lines
9.1 KiB
TypeScript
/**
|
|
* LibreBooking API Test-Skript
|
|
*
|
|
* Testet die Authentifizierung und grundlegende API-Operationen
|
|
* mit den bereitgestellten Test-Credentials.
|
|
*
|
|
* Ausführen mit: npx ts-node test/test-api.ts
|
|
*/
|
|
|
|
const https = require('https');
|
|
const http = require('http');
|
|
|
|
// Test-Credentials
|
|
const TEST_CONFIG = {
|
|
url: 'https://librebooking.zell-cloud.de',
|
|
username: 'sebastian.zell@zell-aufmass.de',
|
|
password: 'wanUQ4uVqU6lfP',
|
|
};
|
|
|
|
interface LibreBookingSession {
|
|
sessionToken: string;
|
|
userId: number;
|
|
sessionExpires: string;
|
|
}
|
|
|
|
/**
|
|
* HTTP/HTTPS Request Helper
|
|
*/
|
|
async function makeRequest(
|
|
url: string,
|
|
method: string,
|
|
headers: Record<string, string>,
|
|
body?: any
|
|
): Promise<any> {
|
|
return new Promise((resolve, reject) => {
|
|
const urlObj = new URL(url);
|
|
const isHttps = urlObj.protocol === 'https:';
|
|
const lib = isHttps ? https : http;
|
|
|
|
const options = {
|
|
hostname: urlObj.hostname,
|
|
port: urlObj.port || (isHttps ? 443 : 80),
|
|
path: urlObj.pathname + urlObj.search,
|
|
method,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...headers,
|
|
},
|
|
};
|
|
|
|
const req = lib.request(options, (res: any) => {
|
|
let data = '';
|
|
res.on('data', (chunk: string) => (data += chunk));
|
|
res.on('end', () => {
|
|
try {
|
|
const jsonData = JSON.parse(data);
|
|
resolve({ statusCode: res.statusCode, data: jsonData });
|
|
} catch (e) {
|
|
resolve({ statusCode: res.statusCode, data });
|
|
}
|
|
});
|
|
});
|
|
|
|
req.on('error', reject);
|
|
|
|
if (body) {
|
|
req.write(JSON.stringify(body));
|
|
}
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Authentifizierung testen
|
|
*/
|
|
async function testAuthentication(): Promise<LibreBookingSession | null> {
|
|
console.log('\n========================================');
|
|
console.log('TEST 1: Authentifizierung');
|
|
console.log('========================================');
|
|
|
|
try {
|
|
const response = await makeRequest(
|
|
`${TEST_CONFIG.url}/Web/Services/index.php/Authentication/Authenticate`,
|
|
'POST',
|
|
{},
|
|
{
|
|
username: TEST_CONFIG.username,
|
|
password: TEST_CONFIG.password,
|
|
}
|
|
);
|
|
|
|
if (response.statusCode === 200 && response.data.isAuthenticated) {
|
|
console.log('✅ Authentifizierung erfolgreich!');
|
|
console.log(` Session Token: ${response.data.sessionToken.substring(0, 20)}...`);
|
|
console.log(` User ID: ${response.data.userId}`);
|
|
console.log(` Session läuft ab: ${response.data.sessionExpires}`);
|
|
return {
|
|
sessionToken: response.data.sessionToken,
|
|
userId: response.data.userId,
|
|
sessionExpires: response.data.sessionExpires,
|
|
};
|
|
} else {
|
|
console.log('❌ Authentifizierung fehlgeschlagen!');
|
|
console.log(' Response:', JSON.stringify(response.data, null, 2));
|
|
return null;
|
|
}
|
|
} catch (error: any) {
|
|
console.log('❌ Fehler bei der Authentifizierung:', error.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alle Reservierungen abrufen
|
|
*/
|
|
async function testGetReservations(session: LibreBookingSession): Promise<void> {
|
|
console.log('\n========================================');
|
|
console.log('TEST 2: Reservierungen abrufen');
|
|
console.log('========================================');
|
|
|
|
try {
|
|
const response = await makeRequest(
|
|
`${TEST_CONFIG.url}/Web/Services/index.php/Reservations/`,
|
|
'GET',
|
|
{
|
|
'X-Booked-SessionToken': session.sessionToken,
|
|
'X-Booked-UserId': session.userId.toString(),
|
|
}
|
|
);
|
|
|
|
if (response.statusCode === 200) {
|
|
const reservations = response.data.reservations || [];
|
|
console.log(`✅ ${reservations.length} Reservierung(en) gefunden`);
|
|
|
|
if (reservations.length > 0) {
|
|
console.log('\n Erste 3 Reservierungen:');
|
|
reservations.slice(0, 3).forEach((res: any, idx: number) => {
|
|
console.log(` ${idx + 1}. ${res.title || 'Ohne Titel'}`);
|
|
console.log(` Referenz: ${res.referenceNumber}`);
|
|
console.log(` Ressource: ${res.resourceName}`);
|
|
console.log(` Zeit: ${res.startDate} - ${res.endDate}`);
|
|
console.log('');
|
|
});
|
|
}
|
|
} else {
|
|
console.log(`❌ Fehler beim Abrufen: Status ${response.statusCode}`);
|
|
console.log(' Response:', JSON.stringify(response.data, null, 2));
|
|
}
|
|
} catch (error: any) {
|
|
console.log('❌ Fehler:', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alle Ressourcen abrufen
|
|
*/
|
|
async function testGetResources(session: LibreBookingSession): Promise<void> {
|
|
console.log('\n========================================');
|
|
console.log('TEST 3: Ressourcen abrufen');
|
|
console.log('========================================');
|
|
|
|
try {
|
|
const response = await makeRequest(
|
|
`${TEST_CONFIG.url}/Web/Services/index.php/Resources/`,
|
|
'GET',
|
|
{
|
|
'X-Booked-SessionToken': session.sessionToken,
|
|
'X-Booked-UserId': session.userId.toString(),
|
|
}
|
|
);
|
|
|
|
if (response.statusCode === 200) {
|
|
const resources = response.data.resources || [];
|
|
console.log(`✅ ${resources.length} Ressource(n) gefunden`);
|
|
|
|
resources.forEach((res: any, idx: number) => {
|
|
console.log(` ${idx + 1}. ${res.name} (ID: ${res.resourceId})`);
|
|
if (res.location) console.log(` Standort: ${res.location}`);
|
|
console.log(` Status: ${res.statusId === 1 ? 'Verfügbar' : res.statusId === 0 ? 'Versteckt' : 'Nicht verfügbar'}`);
|
|
});
|
|
} else {
|
|
console.log(`❌ Fehler beim Abrufen: Status ${response.statusCode}`);
|
|
}
|
|
} catch (error: any) {
|
|
console.log('❌ Fehler:', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alle Zeitpläne abrufen
|
|
*/
|
|
async function testGetSchedules(session: LibreBookingSession): Promise<void> {
|
|
console.log('\n========================================');
|
|
console.log('TEST 4: Zeitpläne abrufen');
|
|
console.log('========================================');
|
|
|
|
try {
|
|
const response = await makeRequest(
|
|
`${TEST_CONFIG.url}/Web/Services/index.php/Schedules/`,
|
|
'GET',
|
|
{
|
|
'X-Booked-SessionToken': session.sessionToken,
|
|
'X-Booked-UserId': session.userId.toString(),
|
|
}
|
|
);
|
|
|
|
if (response.statusCode === 200) {
|
|
const schedules = response.data.schedules || [];
|
|
console.log(`✅ ${schedules.length} Zeitplan/Zeitpläne gefunden`);
|
|
|
|
schedules.forEach((schedule: any, idx: number) => {
|
|
console.log(` ${idx + 1}. ${schedule.name} (ID: ${schedule.id})`);
|
|
console.log(` Zeitzone: ${schedule.timezone}`);
|
|
console.log(` Standard: ${schedule.isDefault ? 'Ja' : 'Nein'}`);
|
|
});
|
|
} else {
|
|
console.log(`❌ Fehler beim Abrufen: Status ${response.statusCode}`);
|
|
}
|
|
} catch (error: any) {
|
|
console.log('❌ Fehler:', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alle Benutzer abrufen
|
|
*/
|
|
async function testGetUsers(session: LibreBookingSession): Promise<void> {
|
|
console.log('\n========================================');
|
|
console.log('TEST 5: Benutzer abrufen');
|
|
console.log('========================================');
|
|
|
|
try {
|
|
const response = await makeRequest(
|
|
`${TEST_CONFIG.url}/Web/Services/index.php/Users/`,
|
|
'GET',
|
|
{
|
|
'X-Booked-SessionToken': session.sessionToken,
|
|
'X-Booked-UserId': session.userId.toString(),
|
|
}
|
|
);
|
|
|
|
if (response.statusCode === 200) {
|
|
const users = response.data.users || [];
|
|
console.log(`✅ ${users.length} Benutzer gefunden`);
|
|
|
|
users.slice(0, 5).forEach((user: any, idx: number) => {
|
|
console.log(` ${idx + 1}. ${user.firstName} ${user.lastName}`);
|
|
console.log(` E-Mail: ${user.emailAddress}`);
|
|
console.log(` ID: ${user.id}`);
|
|
});
|
|
|
|
if (users.length > 5) {
|
|
console.log(` ... und ${users.length - 5} weitere`);
|
|
}
|
|
} else {
|
|
console.log(`❌ Fehler beim Abrufen: Status ${response.statusCode}`);
|
|
}
|
|
} catch (error: any) {
|
|
console.log('❌ Fehler:', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Abmelden
|
|
*/
|
|
async function testSignOut(session: LibreBookingSession): Promise<void> {
|
|
console.log('\n========================================');
|
|
console.log('TEST 6: Abmelden');
|
|
console.log('========================================');
|
|
|
|
try {
|
|
const response = await makeRequest(
|
|
`${TEST_CONFIG.url}/Web/Services/index.php/Authentication/SignOut`,
|
|
'POST',
|
|
{},
|
|
{
|
|
userId: session.userId,
|
|
sessionToken: session.sessionToken,
|
|
}
|
|
);
|
|
|
|
if (response.statusCode === 200 || response.statusCode === 204) {
|
|
console.log('✅ Erfolgreich abgemeldet');
|
|
} else {
|
|
console.log(`⚠️ Abmeldung mit Status ${response.statusCode} abgeschlossen`);
|
|
}
|
|
} catch (error: any) {
|
|
console.log('⚠️ Abmeldung fehlgeschlagen (kann ignoriert werden):', error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hauptfunktion
|
|
*/
|
|
async function runTests(): Promise<void> {
|
|
console.log('\n📝 LibreBooking API Test');
|
|
console.log('======================================');
|
|
console.log(`URL: ${TEST_CONFIG.url}`);
|
|
console.log(`User: ${TEST_CONFIG.username}`);
|
|
console.log('======================================');
|
|
|
|
// Test 1: Authentifizierung
|
|
const session = await testAuthentication();
|
|
|
|
if (!session) {
|
|
console.log('\n❌ Tests abgebrochen - Authentifizierung fehlgeschlagen');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Test 2-5: API-Endpunkte
|
|
await testGetReservations(session);
|
|
await testGetResources(session);
|
|
await testGetSchedules(session);
|
|
await testGetUsers(session);
|
|
|
|
// Test 6: Abmelden
|
|
await testSignOut(session);
|
|
|
|
console.log('\n========================================');
|
|
console.log('✅ Alle Tests abgeschlossen!');
|
|
console.log('========================================\n');
|
|
}
|
|
|
|
// Tests ausführen
|
|
runTests().catch(console.error);
|